diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index c9b86f0a9191bec30e50771f6a1231b92c954a53..7e50afc12a5b1b476d0ec6299105c9033aa9e363 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -2623,51 +2623,71 @@ static int restart_monitor(void)
 	return 0;
 }
 
-static int h323_do_trace(int fd, int argc, char *argv[])
-{
-	if (argc != 4) {
-		return RESULT_SHOWUSAGE;
+static char *handle_cli_h323_set_trace(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "h323 set trace [off]";
+		e->usage =
+			"Usage: h323 set trace (off|<trace level>)\n"
+			"       Enable/Disable H.323 stack tracing for debugging purposes\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
 	}
-	h323_debug(1, atoi(argv[3]));
-	ast_cli(fd, "H.323 trace set to level %s\n", argv[2]);
-	return RESULT_SUCCESS;
-}
 
-static int h323_no_trace(int fd, int argc, char *argv[])
-{
-	if (argc < 3 || argc > 4) {
-		return RESULT_SHOWUSAGE;
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+	if (!strcasecmp(a->argv[3], "off")) {
+		h323_debug(0, 0);
+		ast_cli(a->fd, "H.323 Trace Disabled\n");
+	} else {
+		int tracelevel = atoi(a->argv[3]);
+		h323_debug(1, tracelevel);
+		ast_cli(a->fd, "H.323 Trace Enabled (Trace Level: %d)\n", tracelevel);
 	}
-	h323_debug(0,0);
-	ast_cli(fd, "H.323 trace disabled\n");
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int h323_do_debug(int fd, int argc, char *argv[])
+static char *handle_cli_h323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 2 || argc > 3) {
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "h323 set debug [off]";
+		e->usage =
+			"Usage: h323 set debug [off]\n"
+			"       Enable/Disable H.323 debugging output\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
 	}
-	h323debug = 1;
-	ast_cli(fd, "H.323 debug enabled\n");
-	return RESULT_SUCCESS;
-}
 
-static int h323_no_debug(int fd, int argc, char *argv[])
-{
-	if (argc < 3 || argc > 4) {
-		return RESULT_SHOWUSAGE;
-	}
-	h323debug = 0;
-	ast_cli(fd, "H.323 debug disabled\n");
-	return RESULT_SUCCESS;
+	if (a->argc < 3 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	if (a->argc == 4 && strcasecmp(a->argv[3], "off"))
+		return CLI_SHOWUSAGE;
+
+	h323debug = (a->argc == 3) ? 1 : 0;
+	ast_cli(a->fd, "H.323 Debugging %s\n", h323debug ? "Enabled" : "Disabled");
+	return CLI_SUCCESS;
 }
 
-static int h323_gk_cycle(int fd, int argc, char *argv[])
+static char *handle_cli_h323_cycle_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "h323 cycle gk";
+		e->usage =
+			"Usage: h323 cycle gk\n"
+			"       Manually re-register with the Gatekeper (Currently Disabled)\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
 	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+
 	h323_gk_urq();
 
 	/* Possibly register with a GK */
@@ -2676,126 +2696,59 @@ static int h323_gk_cycle(int fd, int argc, char *argv[])
 			ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
 		}
 	}
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int h323_ep_hangup(int fd, int argc, char *argv[])
+static char *handle_cli_h323_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "h323 hangup";
+		e->usage =
+			"Usage: h323 hangup <token>\n"
+			"       Manually try to hang up the call identified by <token>\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
 	}
-	if (h323_soft_hangup(argv[2])) {
-		ast_verb(3, "Hangup succeeded on %s\n", argv[2]);
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+	if (h323_soft_hangup(a->argv[2])) {
+		ast_verb(3, "Hangup succeeded on %s\n", a->argv[2]);
 	} else {
-		ast_verb(3, "Hangup failed for %s\n", argv[2]);
+		ast_verb(3, "Hangup failed for %s\n", a->argv[2]);
 	}
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int h323_tokens_show(int fd, int argc, char *argv[])
+static char *handle_cli_h323_show_tokens(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "h323 show tokens";
+		e->usage =
+			"Usage: h323 show tokens\n"
+			"       Print out all active call tokens\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
 	}
-	h323_show_tokens();
-	return RESULT_SUCCESS;
-}
-
-static char trace_usage[] =
-"Usage: h323 trace <level num>\n"
-"       Enables H.323 stack tracing for debugging purposes\n";
-
-static char no_trace_usage[] =
-"Usage: h323 no trace\n"
-"       Disables H.323 stack tracing for debugging purposes\n";
-
-static char debug_usage[] =
-"Usage: h323 debug\n"
-"       Enables H.323 debug output\n";
-
-static char no_debug_usage[] =
-"Usage: h323 no debug\n"
-"       Disables H.323 debug output\n";
 
-static char show_cycle_usage[] =
-"Usage: h323 gk cycle\n"
-"       Manually re-register with the Gatekeper (Currently Disabled)\n";
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
 
-static char show_hangup_usage[] =
-"Usage: h323 hangup <token>\n"
-"       Manually try to hang up call identified by <token>\n";
-
-static char show_tokens_usage[] =
-"Usage: h323 show tokens\n"
-"       Print out all active call tokens\n";
-
-static char h323_reload_usage[] =
-"Usage: h323 reload\n"
-"       Reloads H.323 configuration from h323.conf\n";
-
-static struct ast_cli_entry cli_h323_trace_deprecated =
-	{ { "h.323", "trace", NULL },
-	h323_do_trace, "Enable H.323 Stack Tracing",
-	trace_usage };
-
-static struct ast_cli_entry cli_h323_no_trace_deprecated =
-	{ { "h.323", "no", "trace", NULL },
-	h323_no_trace, "Disable H.323 Stack Tracing",
-	no_trace_usage };
-
-static struct ast_cli_entry cli_h323_debug_deprecated =
-	{ { "h.323", "debug", NULL },
-	h323_do_debug, "Enable H.323 debug",
-	debug_usage };
-
-static struct ast_cli_entry cli_h323_no_debug_deprecated =
-	{ { "h.323", "no", "debug", NULL },
-	h323_no_debug, "Disable H.323 debug",
-	no_debug_usage };
-
-static struct ast_cli_entry cli_h323_gk_cycle_deprecated =
-	{ { "h.323", "gk", "cycle", NULL },
-	h323_gk_cycle, "Manually re-register with the Gatekeper",
-	show_cycle_usage };
-
-static struct ast_cli_entry cli_h323_hangup_deprecated =
-	{ { "h.323", "hangup", NULL },
-	h323_ep_hangup, "Manually try to hang up a call",
-	show_hangup_usage };
+	h323_show_tokens();
 
-static struct ast_cli_entry cli_h323_show_tokens_deprecated =
-	{ { "h.323", "show", "tokens", NULL },
-	h323_tokens_show, "Show all active call tokens",
-	show_tokens_usage };
+	return CLI_SUCCESS;
+}
 
 static struct ast_cli_entry cli_h323[] = {
-	{ { "h323", "set", "trace", NULL },
-	h323_do_trace, "Enable H.323 Stack Tracing",
-	trace_usage, NULL, &cli_h323_trace_deprecated },
-
-	{ { "h323", "set", "trace", "off", NULL },
-	h323_no_trace, "Disable H.323 Stack Tracing",
-	no_trace_usage, NULL, &cli_h323_no_trace_deprecated },
-
-	{ { "h323", "set", "debug", NULL },
-	h323_do_debug, "Enable H.323 debug",
-	debug_usage, NULL, &cli_h323_debug_deprecated },
-
-	{ { "h323", "set", "debug", "off", NULL },
-	h323_no_debug, "Disable H.323 debug",
-	no_debug_usage, NULL, &cli_h323_no_debug_deprecated },
-
-	{ { "h323", "cycle", "gk", NULL },
-	h323_gk_cycle, "Manually re-register with the Gatekeper",
-	show_cycle_usage, NULL, &cli_h323_gk_cycle_deprecated },
-
-	{ { "h323", "hangup", NULL },
-	h323_ep_hangup, "Manually try to hang up a call",
-	show_hangup_usage, NULL, &cli_h323_hangup_deprecated },
-
-	{ { "h323", "show", "tokens", NULL },
-	h323_tokens_show, "Show all active call tokens",
-	show_tokens_usage, NULL, &cli_h323_show_tokens_deprecated },
+	NEW_CLI(handle_cli_h323_set_trace,   "Enable/Disable H.323 Stack Tracing"),
+	NEW_CLI(handle_cli_h323_set_debug,   "Enable/Disable H.323 Debugging"),
+	NEW_CLI(handle_cli_h323_cycle_gk,    "Manually re-register with the Gatekeper"),
+	NEW_CLI(handle_cli_h323_hangup,      "Manually try to hang up a call"),
+	NEW_CLI(handle_cli_h323_show_tokens, "Show all active call tokens"),
 };
 
 static int reload_config(int is_reload)
@@ -3075,7 +3028,7 @@ static void prune_peers(void)
 	ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer);
 }
 
-static int h323_reload(int fd, int argc, char *argv[])
+static int h323_reload(void)
 {
 	ast_mutex_lock(&h323_reload_lock);
 	if (h323_reloading) {
@@ -3088,6 +3041,27 @@ static int h323_reload(int fd, int argc, char *argv[])
 	return 0;
 }
 
+static char *handle_cli_h323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "h323 reload";
+		e->usage =
+			"Usage: h323 reload\n"
+			"       Reloads H.323 configuration from h323.conf\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 2)
+		return CLI_SHOWUSAGE;
+
+	h323_reload();
+
+	return CLI_SUCCESS;
+}
+
 static int h323_do_reload(void)
 {
 	reload_config(1);
@@ -3100,20 +3074,11 @@ static int reload(void)
 		ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
 		return 0;
 	}
-	return h323_reload(0, 0, NULL);
+	return h323_reload();
 }
 
-static struct ast_cli_entry cli_h323_reload_deprecated =
-	{ { "h.323", "reload", NULL },
-	h323_reload, "Reload H.323 configuration",
-	h323_reload_usage
-};
-
 static struct ast_cli_entry cli_h323_reload =
-	{ { "h323", "reload", NULL },
-	h323_reload, "Reload H.323 configuration",
-	h323_reload_usage, NULL, &cli_h323_reload_deprecated
-};
+	NEW_CLI(handle_cli_h323_reload, "Reload H.323 configuration");
 
 static enum ast_rtp_get_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
 {
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 7c62f7af7e022e4ec0eda66720ad67f9a1d20080..30af97a9d8e5faaaf725f2af42b7077c8d20ef71 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -292,8 +292,6 @@ enum iax2_flags {
 static int global_rtautoclear = 120;
 
 static int reload_config(void);
-static int iax2_reload(int fd, int argc, char *argv[]);
-
 
 struct iax2_user {
 	AST_DECLARE_STRING_FIELDS(
@@ -711,6 +709,8 @@ static void reg_source_db(struct iax2_peer *p);
 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
 
 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
+static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state);
+static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
 
 enum iax2_thread_iostate {
 	IAX_IOSTATE_IDLE,
@@ -2265,72 +2265,128 @@ static int attempt_transmit(const void *data)
 	return 0;
 }
 
-static int iax2_prune_realtime(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct iax2_peer *peer;
 
-	if (argc != 4)
-        return RESULT_SHOWUSAGE;
-	if (!strcmp(argv[3],"all")) {
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 prune realtime";
+		e->usage =
+			"Usage: iax2 prune realtime [<peername>|all]\n"
+			"       Prunes object(s) from the cache\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_iax2_show_peer(a->line, a->word, a->pos, a->n);
+	}
+
+	if (a->argc != 4)
+        return CLI_SHOWUSAGE;
+	if (!strcmp(a->argv[3], "all")) {
 		reload_config();
-		ast_cli(fd, "OK cache is flushed.\n");
-	} else if ((peer = find_peer(argv[3], 0))) {
+		ast_cli(a->fd, "Cache flushed successfully.\n");
+	} else if ((peer = find_peer(a->argv[3], 0))) {
 		if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
 			ast_set_flag(peer, IAX_RTAUTOCLEAR);
-			expire_registry((const void *)peer->name);
-			ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
+			expire_registry((const void *) peer->name);
+			ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
 		} else {
-			ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
+			ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
 		}
 		peer_unref(peer);
 	} else {
-		ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
+		ast_cli(a->fd, "Peer %s was not found in the cache.\n", a->argv[3]);
 	}
 	
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int iax2_test_losspct(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 test losspct";
+		e->usage =
+			"Usage: iax2 test losspct <percentage>\n"
+			"       For testing, throws away <percentage> percent of incoming packets\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-       test_losspct = atoi(argv[3]);
+	test_losspct = atoi(a->argv[3]);
 
-       return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 #ifdef IAXTESTS
-static int iax2_test_late(int fd, int argc, char *argv[])
-{
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
+static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 test late";
+		e->usage =
+			"Usage: iax2 test late <ms>\n"
+			"       For testing, count the next frame as <ms> ms late\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	test_late = atoi(argv[3]);
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	return RESULT_SUCCESS;
+	test_late = atoi(a->argv[3]);
+
+	return CLI_SUCCESS;
 }
 
-static int iax2_test_resync(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 test resync";
+		e->usage =
+			"Usage: iax2 test resync <ms>\n"
+			"       For testing, adjust all future frames by <ms> ms\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	test_resync = atoi(argv[3]);
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	return RESULT_SUCCESS;
+	test_resync = atoi(a->argv[3]);
+
+	return CLI_SUCCESS;
 }
 
-static int iax2_test_jitter(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 4 || argc > 5)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 test jitter";
+		e->usage =
+			"Usage: iax2 test jitter <ms> <pct>\n"
+			"       For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
+			"       percentage of packets. If <pct> is not specified, adds\n"
+			"       jitter to all packets.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	test_jit = atoi(argv[3]);
-	if (argc == 5) 
-		test_jitpct = atoi(argv[4]);
+	if (a->argc < 4 || a->argc > 5)
+		return CLI_SHOWUSAGE;
 
-	return RESULT_SUCCESS;
+	test_jit = atoi(a->argv[3]);
+	if (a->argc == 5)
+		test_jitpct = atoi(a->argv[4]);
+
+	return CLI_SUCCESS;
 }
 #endif /* IAXTESTS */
 
@@ -2359,7 +2415,7 @@ static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
 }
 
 /*! \brief Show one peer in detail */
-static int iax2_show_peer(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char status[30];
 	char cbuf[256];
@@ -2367,55 +2423,66 @@ static int iax2_show_peer(int fd, int argc, char *argv[])
 	char codec_buf[512];
 	int x = 0, codec = 0, load_realtime = 0;
 
-	if (argc < 4)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show peer";
+		e->usage =
+			"Usage: iax2 show peer <name>\n"
+			"       Display details on specific IAX peer\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_iax2_show_peer(a->line, a->word, a->pos, a->n);
+	}
+
+	if (a->argc < 4)
+		return CLI_SHOWUSAGE;
 
-	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
+	load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
 
-	peer = find_peer(argv[3], load_realtime);
+	peer = find_peer(a->argv[3], load_realtime);
 	if (peer) {
-		ast_cli(fd,"\n\n");
-		ast_cli(fd, "  * Name       : %s\n", peer->name);
-		ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
-		ast_cli(fd, "  Context      : %s\n", peer->context);
-		ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
-		ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
-		ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
-		ast_cli(fd, "  Expire       : %d\n", peer->expire);
-		ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
-		ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
-		ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
-		ast_cli(fd, "  Username     : %s\n", peer->username);
-		ast_cli(fd, "  Codecs       : ");
+		ast_cli(a->fd, "\n\n");
+		ast_cli(a->fd, "  * Name       : %s\n", peer->name);
+		ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
+		ast_cli(a->fd, "  Context      : %s\n", peer->context);
+		ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
+		ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
+		ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
+		ast_cli(a->fd, "  Expire       : %d\n", peer->expire);
+		ast_cli(a->fd, "  ACL          : %s\n", (peer->ha ? "Yes" : "No"));
+		ast_cli(a->fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
+		ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
+		ast_cli(a->fd, "  Username     : %s\n", peer->username);
+		ast_cli(a->fd, "  Codecs       : ");
 		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
-		ast_cli(fd, "%s\n", codec_buf);
+		ast_cli(a->fd, "%s\n", codec_buf);
 
-		ast_cli(fd, "  Codec Order  : (");
+		ast_cli(a->fd, "  Codec Order  : (");
 		for(x = 0; x < 32 ; x++) {
 			codec = ast_codec_pref_index(&peer->prefs,x);
 			if(!codec)
 				break;
-			ast_cli(fd, "%s", ast_getformatname(codec));
+			ast_cli(a->fd, "%s", ast_getformatname(codec));
 			if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
-				ast_cli(fd, "|");
+				ast_cli(a->fd, "|");
 		}
 
 		if (!x)
-			ast_cli(fd, "none");
-		ast_cli(fd, ")\n");
+			ast_cli(a->fd, "none");
+		ast_cli(a->fd, ")\n");
 
-		ast_cli(fd, "  Status       : ");
+		ast_cli(a->fd, "  Status       : ");
 		peer_status(peer, status, sizeof(status));	
-		ast_cli(fd, "%s\n",status);
-		ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
-		ast_cli(fd,"\n");
+		ast_cli(a->fd, "%s\n",status);
+		ast_cli(a->fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
+		ast_cli(a->fd, "\n");
 		peer_unref(peer);
 	} else {
-		ast_cli(fd,"Peer %s not found.\n", argv[3]);
-		ast_cli(fd,"\n");
+		ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
+		ast_cli(a->fd, "\n");
 	}
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
@@ -2443,13 +2510,24 @@ static char *complete_iax2_show_peer(const char *line, const char *word, int pos
 	return res;
 }
 
-static int iax2_show_stats(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct iax_frame *cur;
-	int cnt = 0, dead=0, final=0;
+	int cnt = 0, dead = 0, final = 0;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show stats";
+		e->usage =
+			"Usage: iax2 show stats\n"
+			"       Display statistics on IAX channel driver.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
 
 	AST_LIST_LOCK(&frame_queue);
 	AST_LIST_TRAVERSE(&frame_queue, cur, list) {
@@ -2461,57 +2539,83 @@ static int iax2_show_stats(int fd, int argc, char *argv[])
 	}
 	AST_LIST_UNLOCK(&frame_queue);
 
-	ast_cli(fd, "    IAX Statistics\n");
-	ast_cli(fd, "---------------------\n");
-	ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
-	ast_cli(fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
+	ast_cli(a->fd, "    IAX Statistics\n");
+	ast_cli(a->fd, "---------------------\n");
+	ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
+	ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
 		trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
-
-	ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
+	ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
 
 	trunk_timed = trunk_untimed = 0;
 	if (trunk_maxmtu > trunk_nmaxmtu)
 		trunk_nmaxmtu = trunk_maxmtu;
-	
-	return RESULT_SUCCESS;
+
+	return CLI_SUCCESS;
 }
 
 /*! \brief Set trunk MTU from CLI */
-static int iax2_set_mtu(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int mtuv;
 
-	if (argc != 4)
-		return RESULT_SHOWUSAGE; 
-	if (strncasecmp(argv[3], "default", strlen(argv[3])) == 0) 
-		mtuv = MAX_TRUNK_MTU; 
-	else                                         
-		mtuv = atoi(argv[3]); 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set mtu";
+		e->usage =
+			"Usage: iax2 set mtu <value>\n"
+			"       Set the system-wide IAX IP mtu to <value> bytes net or\n"
+			"       zero to disable. Disabling means that the operating system\n"
+			"       must handle fragmentation of UDP packets when the IAX2 trunk\n"
+			"       packet exceeds the UDP payload size. This is substantially\n"
+			"       below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
+			"       greater for G.711 samples.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE; 
+	if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
+		mtuv = MAX_TRUNK_MTU;
+	else
+		mtuv = atoi(a->argv[3]);
 
 	if (mtuv == 0) {
-		ast_cli(fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
+		ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
 		global_max_trunk_mtu = 0; 
-		return RESULT_SUCCESS; 
+		return CLI_SUCCESS; 
 	}
 	if (mtuv < 172 || mtuv > 4000) {
-		ast_cli(fd, "Trunk MTU must be between 172 and 4000\n"); 
-		return RESULT_SHOWUSAGE; 
+		ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 
+		return CLI_SHOWUSAGE; 
 	}
-	ast_cli(fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
+	ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
 	global_max_trunk_mtu = mtuv; 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int iax2_show_cache(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct iax2_dpcache *dp = NULL;
 	char tmp[1024], *pc = NULL;
 	int s, x, y;
 	struct timeval tv = ast_tvnow();
 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show cache";
+		e->usage =
+			"Usage: iax2 show cache\n"
+			"       Display currently cached IAX Dialplan results.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
 	AST_LIST_LOCK(&dpcache);
 
-	ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
+	ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
 
 	AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
 		s = dp->expiry.tv_sec - tv.tv_sec;
@@ -2537,24 +2641,24 @@ static int iax2_show_cache(int fd, int argc, char *argv[])
 			tmp[strlen(tmp) - 1] = '\0';
 		else
 			ast_copy_string(tmp, "(none)", sizeof(tmp));
-		y=0;
+		y = 0;
 		pc = strchr(dp->peercontext, '@');
 		if (!pc)
 			pc = dp->peercontext;
 		else
 			pc++;
-		for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
+		for (x = 0; x < sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
 			if (dp->waiters[x] > -1)
 				y++;
 		if (s > 0)
-			ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
+			ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
 		else
-			ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
+			ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
 	}
 
 	AST_LIST_LOCK(&dpcache);
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
@@ -4424,7 +4528,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 	return res;
 }
 
-static int iax2_show_users(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	regex_t regexbuf;
 	int havepattern = 0;
@@ -4437,21 +4541,33 @@ static int iax2_show_users(int fd, int argc, char *argv[])
 	char *pstr = "";
 	struct ao2_iterator i;
 
-	switch (argc) {
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show users [like]";
+		e->usage =
+			"Usage: iax2 show users [like <pattern>]\n"
+			"       Lists all known IAX2 users.\n"
+			"       Optional regular expression pattern is used to filter the user list.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	switch (a->argc) {
 	case 5:
-		if (!strcasecmp(argv[3], "like")) {
-			if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
-				return RESULT_SHOWUSAGE;
+		if (!strcasecmp(a->argv[3], "like")) {
+			if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
+				return CLI_SHOWUSAGE;
 			havepattern = 1;
 		} else
-			return RESULT_SHOWUSAGE;
+			return CLI_SHOWUSAGE;
 	case 3:
 		break;
 	default:
-		return RESULT_SHOWUSAGE;
+		return CLI_SHOWUSAGE;
 	}
 
-	ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
+	ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
 	i = ao2_iterator_init(users, 0);
 	for (user = ao2_iterator_next(&i); user; 
 		user_unref(user), user = ao2_iterator_next(&i)) {
@@ -4459,7 +4575,7 @@ static int iax2_show_users(int fd, int argc, char *argv[])
 			continue;
 		
 		if (!ast_strlen_zero(user->secret)) {
-  			ast_copy_string(auth,user->secret,sizeof(auth));
+  			ast_copy_string(auth,user->secret, sizeof(auth));
 		} else if (!ast_strlen_zero(user->inkeys)) {
   			snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
  		} else
@@ -4472,7 +4588,7 @@ static int iax2_show_users(int fd, int argc, char *argv[])
 		else
 			pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
 		
-		ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
+		ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 
 			user->contexts ? user->contexts->context : context,
 			user->ha ? "Yes" : "No", pstr);
 	}
@@ -4480,7 +4596,7 @@ static int iax2_show_users(int fd, int argc, char *argv[])
 	if (havepattern)
 		regfree(&regexbuf);
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
@@ -4612,32 +4728,42 @@ static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc
 #undef FORMAT2
 }
 
-static int iax2_show_threads(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct iax2_thread *thread = NULL;
 	time_t t;
 	int threadcount = 0, dynamiccount = 0;
 	char type;
 
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show threads";
+		e->usage =
+			"Usage: iax2 show threads\n"
+			"       Lists status of IAX helper threads\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
 		
-	ast_cli(fd, "IAX2 Thread Information\n");
+	ast_cli(a->fd, "IAX2 Thread Information\n");
 	time(&t);
-	ast_cli(fd, "Idle Threads:\n");
+	ast_cli(a->fd, "Idle Threads:\n");
 	AST_LIST_LOCK(&idle_list);
 	AST_LIST_TRAVERSE(&idle_list, thread, list) {
 #ifdef DEBUG_SCHED_MULTITHREAD
-		ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
+		ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 
 			thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
 #else
-		ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
+		ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
 			thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
 #endif
 		threadcount++;
 	}
 	AST_LIST_UNLOCK(&idle_list);
-	ast_cli(fd, "Active Threads:\n");
+	ast_cli(a->fd, "Active Threads:\n");
 	AST_LIST_LOCK(&active_list);
 	AST_LIST_TRAVERSE(&active_list, thread, list) {
 		if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
@@ -4645,50 +4771,62 @@ static int iax2_show_threads(int fd, int argc, char *argv[])
 		else
 			type = 'P';
 #ifdef DEBUG_SCHED_MULTITHREAD
-		ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
+		ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 
 			type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
 #else
-		ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
+		ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
 			type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
 #endif
 		threadcount++;
 	}
 	AST_LIST_UNLOCK(&active_list);
-	ast_cli(fd, "Dynamic Threads:\n");
+	ast_cli(a->fd, "Dynamic Threads:\n");
 	AST_LIST_LOCK(&dynamic_list);
 	AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
 #ifdef DEBUG_SCHED_MULTITHREAD
-		ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
+		ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
 			thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
 #else
-		ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
+		ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
 			thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
 #endif
 		dynamiccount++;
 	}
 	AST_LIST_UNLOCK(&dynamic_list);
-	ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
-	return RESULT_SUCCESS;
+	ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
+	return CLI_SUCCESS;
 }
 
-static int iax2_unregister(int fd, int argc, char *argv[]) {
+static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
 	struct iax2_peer *p;
 
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 unregister";
+		e->usage =
+			"Usage: iax2 unregister <peername>\n"
+			"       Unregister (force expiration) an IAX2 peer from the registry.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
+	}
 
-	p = find_peer(argv[2], 1);	
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+
+	p = find_peer(a->argv[2], 1);
 	if (p) {
 		if (p->expire > 0) {
-			expire_registry(argv[2]);
-			ast_cli(fd, "Peer %s unregistered\n", argv[2]);
+			expire_registry(a->argv[2]);
+			ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
 		} else {
-			ast_cli(fd, "Peer %s not registered\n", argv[2]);
+			ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
 		}
 	} else {
-		ast_cli(fd, "Peer unknown: %s. Not unregistered\n", argv[2]);
+		ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
 	}
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
@@ -4715,10 +4853,31 @@ static char *complete_iax2_unregister(const char *line, const char *word, int po
 	return res;
 }
 
-static int iax2_show_peers(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	return __iax2_show_peers(0, fd, NULL, argc, argv);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show peers";
+		e->usage =
+			"Usage: iax2 show peers [registered] [like <pattern>]\n"
+			"       Lists all known IAX2 peers.\n"
+			"       Optional 'registered' argument lists only peers with known addresses.\n"
+			"       Optional regular expression pattern is used to filter the peer list.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
+	case RESULT_SHOWUSAGE:
+		return CLI_SHOWUSAGE;
+	case RESULT_FAILURE:
+		return CLI_FAILURE;
+	default:
+		return CLI_SUCCESS;
+	}
 }
+
 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
 {
 	ast_cli_netstats(s, -1, 0);
@@ -4726,24 +4885,35 @@ static int manager_iax2_show_netstats(struct mansession *s, const struct message
 	return RESULT_SUCCESS;
 }
 
-static int iax2_show_firmware(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct iax_firmware *cur = NULL;
 
-	if ((argc != 3) && (argc != 4))
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show firmware";
+		e->usage =
+			"Usage: iax2 show firmware\n"
+			"       Lists all known IAX firmware images.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3 && a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	ast_cli(fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
+	ast_cli(a->fd, "%-15.15s  %-15.15s %-15.15s\n", "Device", "Version", "Size");
 	AST_LIST_LOCK(&firmwares);
 	AST_LIST_TRAVERSE(&firmwares, cur, list) {
-		if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))  {
-			ast_cli(fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
+		if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname)))  {
+			ast_cli(a->fd, "%-15.15s  %-15d %-15d\n", cur->fwh->devname, 
 				ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
 		}
 	}
 	AST_LIST_UNLOCK(&firmwares);
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 /* JDG: callback to display iax peers in manager */
@@ -4781,18 +4951,28 @@ static char *regstate2str(int regstate)
 	}
 }
 
-static int iax2_show_registry(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
 	struct iax2_registry *reg = NULL;
-
 	char host[80];
 	char perceived[80];
 	int counter = 0;
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show registry";
+		e->usage =
+			"Usage: iax2 show registry\n"
+			"       Lists all registration requests and status.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+	ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
 	AST_LIST_LOCK(&registrations);
 	AST_LIST_TRAVERSE(&registrations, reg, entry) {
 		snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
@@ -4800,19 +4980,19 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
 			snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
 		else
 			ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
-		ast_cli(fd, FORMAT, host, 
+		ast_cli(a->fd, FORMAT, host, 
 					(reg->dnsmgr) ? "Y" : "N", 
 					reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
 		counter++;
 	}
 	AST_LIST_UNLOCK(&registrations);
-	ast_cli(fd, "%d IAX2 registrations.\n", counter);
-	return RESULT_SUCCESS;
+	ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
+	return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
-static int iax2_show_channels(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s\n"
@@ -4820,16 +5000,27 @@ static int iax2_show_channels(int fd, int argc, char *argv[])
 	int x;
 	int numchans = 0;
 
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
-	for (x=0;x<IAX_MAX_CALLS;x++) {
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show channels";
+		e->usage =
+			"Usage: iax2 show channels\n"
+			"       Lists all currently active IAX channels.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+	ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
+	for (x = 0; x < IAX_MAX_CALLS; x++) {
 		ast_mutex_lock(&iaxsl[x]);
 		if (iaxs[x]) {
 			int lag, jitter, localdelay;
 			jb_info jbinfo;
 			
-			if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
+			if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
 				jb_getinfo(iaxs[x]->jb, &jbinfo);
 				jitter = jbinfo.jitter;
 				localdelay = jbinfo.current - jbinfo.min;
@@ -4838,7 +5029,7 @@ static int iax2_show_channels(int fd, int argc, char *argv[])
 				localdelay = 0;
 			}
 			lag = iaxs[x]->remote_rr.delay;
-			ast_cli(fd, FORMAT,
+			ast_cli(a->fd, FORMAT,
 				iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
 				ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
 				S_OR(iaxs[x]->username, "(None)"),
@@ -4852,8 +5043,8 @@ static int iax2_show_channels(int fd, int argc, char *argv[])
 		}
 		ast_mutex_unlock(&iaxsl[x]);
 	}
-	ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
-	return RESULT_SUCCESS;
+	ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
+	return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 #undef FORMATB
@@ -4935,70 +5126,141 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
 	return numchans;
 }
 
-static int iax2_show_netstats(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int numchans = 0;
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
-	ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
-	numchans = ast_cli_netstats(NULL, fd, 1);
-	ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
-	return RESULT_SUCCESS;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 show netstats";
+		e->usage =
+			"Usage: iax2 show netstats\n"
+			"       Lists network status for all currently active IAX channels.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+	ast_cli(a->fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
+	ast_cli(a->fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
+	numchans = ast_cli_netstats(NULL, a->fd, 1);
+	ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
+	return CLI_SUCCESS;
 }
 
-static int iax2_do_debug(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 2 || argc > 3)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set debug";
+		e->usage =
+			"Usage: iax2 set debug\n"
+			"       Enables dumping of IAX packets for debugging purposes.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 2 || a->argc > 3)
+		return CLI_SHOWUSAGE;
 	iaxdebug = 1;
-	ast_cli(fd, "IAX2 Debugging Enabled\n");
-	return RESULT_SUCCESS;
+	ast_cli(a->fd, "IAX2 Debugging Enabled\n");
+	return CLI_SUCCESS;
 }
 
-static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_debug_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 3 || argc > 4)
-		return RESULT_SHOWUSAGE;
-	iaxtrunkdebug = 1;
-	ast_cli(fd, "IAX2 Trunk Debug Requested\n");
-	return RESULT_SUCCESS;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set debug off";
+		e->usage =
+			"Usage: iax2 set debug off\n"
+			"       Disables dumping of IAX packets for debugging purposes.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 3 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	iaxdebug = 0;
+	ast_cli(a->fd, "IAX2 Debugging Disabled\n");
+	return CLI_SUCCESS;
 }
 
-static int iax2_do_jb_debug(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 3 || argc > 4)
-		return RESULT_SHOWUSAGE;
-	jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
-	ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
-	return RESULT_SUCCESS;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set debug trunk";
+		e->usage =
+			"Usage: iax2 set debug trunk\n"
+			"       Requests current status of IAX trunking\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 3 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	iaxtrunkdebug = 1;
+	ast_cli(a->fd, "IAX2 Trunk Debugging Requested\n");
+	return CLI_SUCCESS;
 }
 
-static int iax2_no_debug(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_debug_trunk_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 3 || argc > 4)
-		return RESULT_SHOWUSAGE;
-	iaxdebug = 0;
-	ast_cli(fd, "IAX2 Debugging Disabled\n");
-	return RESULT_SUCCESS;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set debug trunk off";
+		e->usage =
+			"Usage: iax2 set debug trunk off\n"
+			"       Disables debugging of IAX trunking\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 4 || a->argc > 5)
+		return CLI_SHOWUSAGE;
+	iaxtrunkdebug = 0;
+	ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
+	return CLI_SUCCESS;
 }
 
-static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 4 || argc > 5)
-		return RESULT_SHOWUSAGE;
-	iaxtrunkdebug = 0;
-	ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
-	return RESULT_SUCCESS;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set debug jb";
+		e->usage =
+			"Usage: iax2 set debug jb\n"
+			"       Enables jitterbuffer debugging information\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 3 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
+	ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
+	return CLI_SUCCESS;
 }
 
-static int iax2_no_jb_debug(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_set_debug_jb_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc < 4 || argc > 5)
-		return RESULT_SHOWUSAGE;
-	iaxtrunkdebug = 0;
-	ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
-	return RESULT_SUCCESS;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 set debug jb off";
+		e->usage =
+			"Usage: iax2 set debug jb off\n"
+			"       Disables jitterbuffer debugging information\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 4 || a->argc > 5)
+		return CLI_SHOWUSAGE;
+	jb_setoutput(jb_error_output, jb_warning_output, NULL);
+	ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
+	return CLI_SUCCESS;
 }
 
 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
@@ -8841,13 +9103,6 @@ static int iax2_do_register(struct iax2_registry *reg)
 	return 0;
 }
 
-static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
-{
-	if (pos != 3)
-		return NULL;
-	return iax_prov_complete_template(line, word, pos, state);
-}
-
 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
 {
 	/* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
@@ -8935,27 +9190,43 @@ static int iax2_prov_app(struct ast_channel *chan, void *data)
 	return res;
 }
 
-
-static int iax2_prov_cmd(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int force = 0;
 	int res;
-	if (argc < 4)
-		return RESULT_SHOWUSAGE;
-	if ((argc > 4)) {
-		if (!strcasecmp(argv[4], "forced"))
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 provision";
+		e->usage = 
+			"Usage: iax2 provision <host> <template> [forced]\n"
+			"       Provisions the given peer or IP address using a template\n"
+			"       matching either 'template' or '*' if the template is not\n"
+			"       found.  If 'forced' is specified, even empty provisioning\n"
+			"       fields will be provisioned as empty fields.\n";
+		return NULL;
+	case CLI_GENERATE:
+		if (a->pos == 3)
+			return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
+		return NULL;
+	}
+
+	if (a->argc < 4)
+		return CLI_SHOWUSAGE;
+	if (a->argc > 4) {
+		if (!strcasecmp(a->argv[4], "forced"))
 			force = 1;
 		else
-			return RESULT_SHOWUSAGE;
+			return CLI_SHOWUSAGE;
 	}
-	res = iax2_provision(NULL, -1, argv[2], argv[3], force);
+	res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
 	if (res < 0)
-		ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
+		ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
 	else if (res < 1)
-		ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
+		ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
 	else
-		ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
-	return RESULT_SUCCESS;
+		ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
+	return CLI_SUCCESS;
 }
 
 static void __iax2_poke_noanswer(const void *data)
@@ -10402,9 +10673,22 @@ static int reload_config(void)
 	return 0;
 }
 
-static int iax2_reload(int fd, int argc, char *argv[])
+static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	return reload_config();
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "iax2 reload";
+		e->usage =
+			"Usage: iax2 reload\n"
+			"       Reloads IAX configuration from iax.conf\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	reload_config();
+
+	return CLI_SUCCESS;
 }
 
 static int reload(void)
@@ -10908,126 +11192,15 @@ static int iax2_devicestate(void *data)
 
 static struct ast_switch iax2_switch = 
 {
-	name: 			"IAX2",
-	description: 		"IAX Remote Dialplan Switch",
-	exists:			iax2_exists,
-	canmatch:		iax2_canmatch,
-	exec:			iax2_exec,
-	matchmore:		iax2_matchmore,
+	name:        "IAX2",
+	description: "IAX Remote Dialplan Switch",
+	exists:      iax2_exists,
+	canmatch:    iax2_canmatch,
+	exec:        iax2_exec,
+	matchmore:   iax2_matchmore,
 };
 
-static const char show_stats_usage[] =
-"Usage: iax2 show stats\n"
-"       Display statistics on IAX channel driver.\n";
-
-static const char set_mtu_usage[] =
-"Usage: iax2 set mtu <value>\n"
-"       Set the system-wide IAX IP mtu to <value> bytes net or zero to disable.\n"
-"       Disabling means that the operating system must handle fragmentation of UDP packets\n"
-"       when the IAX2 trunk packet exceeds the UDP payload size.\n"
-"       This is substantially below the IP mtu. Try 1240 on ethernets.\n"
-"       Must be 172 or greater for G.711 samples.\n"; 
-static const char show_cache_usage[] =
-"Usage: iax2 show cache\n"
-"       Display currently cached IAX Dialplan results.\n";
-
-static const char show_peer_usage[] =
-"Usage: iax2 show peer <name>\n"
-"       Display details on specific IAX peer\n";
-
-static const char prune_realtime_usage[] =
-"Usage: iax2 prune realtime [<peername>|all]\n"
-"       Prunes object(s) from the cache\n";
-
-static const char iax2_reload_usage[] =
-"Usage: iax2 reload\n"
-"       Reloads IAX configuration from iax.conf\n";
-
-static const char show_prov_usage[] =
-"Usage: iax2 provision <host> <template> [forced]\n"
-"       Provisions the given peer or IP address using a template\n"
-"       matching either 'template' or '*' if the template is not\n"
-"       found.  If 'forced' is specified, even empty provisioning\n"
-"       fields will be provisioned as empty fields.\n";
-
-static const char show_users_usage[] = 
-"Usage: iax2 show users [like <pattern>]\n"
-"       Lists all known IAX2 users.\n"
-"       Optional regular expression pattern is used to filter the user list.\n";
-
-static const char show_channels_usage[] = 
-"Usage: iax2 show channels\n"
-"       Lists all currently active IAX channels.\n";
-
-static const char show_netstats_usage[] = 
-"Usage: iax2 show netstats\n"
-"       Lists network status for all currently active IAX channels.\n";
-
-static const char show_threads_usage[] = 
-"Usage: iax2 show threads\n"
-"       Lists status of IAX helper threads\n";
-
-static const char unregister_usage[] =
-"Usage: iax2 unregister <peername>\n"
-"       Unregister (force expiration) an IAX2 peer from the registry.\n";
-
-static const char show_peers_usage[] = 
-"Usage: iax2 show peers [registered] [like <pattern>]\n"
-"       Lists all known IAX2 peers.\n"
-"       Optional 'registered' argument lists only peers with known addresses.\n"
-"       Optional regular expression pattern is used to filter the peer list.\n";
-
-static const char show_firmware_usage[] = 
-"Usage: iax2 show firmware\n"
-"       Lists all known IAX firmware images.\n";
-
-static const char show_reg_usage[] =
-"Usage: iax2 show registry\n"
-"       Lists all registration requests and status.\n";
-
-static const char debug_usage[] = 
-"Usage: iax2 set debug\n"
-"       Enables dumping of IAX packets for debugging purposes\n";
-
-static const char no_debug_usage[] = 
-"Usage: iax2 set debug off\n"
-"       Disables dumping of IAX packets for debugging purposes\n";
-
-static const char debug_trunk_usage[] =
-"Usage: iax2 set debug trunk\n"
-"       Requests current status of IAX trunking\n";
-
-static const char no_debug_trunk_usage[] =
-"Usage: iax2 set debug trunk off\n"
-"       Requests current status of IAX trunking\n";
-
-static const char debug_jb_usage[] =
-"Usage: iax2 set debug jb\n"
-"       Enables jitterbuffer debugging information\n";
-
-static const char no_debug_jb_usage[] =
-"Usage: iax2 set debug jb off\n"
-"       Disables jitterbuffer debugging information\n";
-
-static const char iax2_test_losspct_usage[] =
-"Usage: iax2 test losspct <percentage>\n"
-"       For testing, throws away <percentage> percent of incoming packets\n";
-
-#ifdef IAXTESTS
-static const char iax2_test_late_usage[] =
-"Usage: iax2 test late <ms>\n"
-"       For testing, count the next frame as <ms> ms late\n";
-
-static const char iax2_test_resync_usage[] =
-"Usage: iax2 test resync <ms>\n"
-"       For testing, adjust all future frames by <ms> ms\n";
-
-static const char iax2_test_jitter_usage[] =
-"Usage: iax2 test jitter <ms> <pct>\n"
-"       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
-#endif /* IAXTESTS */
-
-static struct ast_cli_entry cli_iax2[] = {
+/*
 	{ { "iax2", "show", "cache", NULL },
 	iax2_show_cache, "Display IAX cached dialplan",
 	show_cache_usage },
@@ -11128,6 +11301,36 @@ static struct ast_cli_entry cli_iax2[] = {
 	{ { "iax2", "test", "jitter", NULL },
 	iax2_test_jitter, "Simulates jitter for testing",
 	iax2_test_jitter_usage },
+#endif
+*/
+
+static struct ast_cli_entry cli_iax2[] = {
+	NEW_CLI(handle_cli_iax2_provision,           "Provision an IAX device"),
+	NEW_CLI(handle_cli_iax2_prune_realtime,      "Prune a cached realtime lookup"),
+	NEW_CLI(handle_cli_iax2_reload,              "Reload IAX configuration"),
+	NEW_CLI(handle_cli_iax2_set_mtu,             "Set the IAX systemwide trunking MTU"),
+	NEW_CLI(handle_cli_iax2_set_debug,           "Enable IAX debugging"),
+	NEW_CLI(handle_cli_iax2_set_debug_trunk,     "Enable IAX trunk debugging"),
+	NEW_CLI(handle_cli_iax2_set_debug_jb,        "Enable IAX jitterbuffer debugging"),
+	NEW_CLI(handle_cli_iax2_set_debug_off,       "Disable IAX debugging"),
+	NEW_CLI(handle_cli_iax2_set_debug_trunk_off, "Disable IAX trunk debugging"),
+	NEW_CLI(handle_cli_iax2_set_debug_jb_off,    "Disable IAX jitterbuffer debugging"),
+	NEW_CLI(handle_cli_iax2_show_cache,          "Display IAX cached dialplan"),
+	NEW_CLI(handle_cli_iax2_show_channels,       "List active IAX channels"),
+	NEW_CLI(handle_cli_iax2_show_firmware,       "List available IAX firmware"),
+	NEW_CLI(handle_cli_iax2_show_netstats,       "List active IAX channel netstats"),
+	NEW_CLI(handle_cli_iax2_show_peer,           "Show details on specific IAX peer"),
+	NEW_CLI(handle_cli_iax2_show_peers,          "List defined IAX peers"),
+	NEW_CLI(handle_cli_iax2_show_registry,       "Display IAX registration status"),
+	NEW_CLI(handle_cli_iax2_show_stats,          "Display IAX statistics"),
+	NEW_CLI(handle_cli_iax2_show_threads,        "Display IAX helper thread info"),
+	NEW_CLI(handle_cli_iax2_show_users,          "List defined IAX users"),
+	NEW_CLI(handle_cli_iax2_test_losspct,        "Set IAX2 incoming frame loss percentage"),
+	NEW_CLI(handle_cli_iax2_unregister,          "Unregister (force expiration) an IAX2 peer from the registry"),
+#ifdef IAXTESTS
+	NEW_CLI(handle_cli_iax2_test_jitter,         "Simulates jitter for testing"),
+	NEW_CLI(handle_cli_iax2_test_late,           "Test the receipt of a late frame"),
+	NEW_CLI(handle_cli_iax2_test_resync,         "Test a resync in received timestamps"),
 #endif /* IAXTESTS */
 };
 
@@ -11342,4 +11545,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange
 		.load = load_module,
 		.unload = unload_module,
 		.reload = reload,
-	       );
+		);
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 1eaa64084a609eea7250b7819fc9cc736e519cfb..f9119413f997244531a5417c3713dda707ab9a61 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -114,6 +114,9 @@ available data is returned and the return value indicates the number
 of data. */
 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
 
+static char *complete_ch(struct ast_cli_args *a);
+static char *complete_debug_port(struct ast_cli_args *a);
+static char *complete_show_config(struct ast_cli_args *a);
 
 /* BEGIN: chan_misdn.h */
 
@@ -735,24 +738,36 @@ static void send_digit_to_chan(struct chan_list *cl, char digit )
 		ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
 	}
 }
+
 /*** CLI HANDLING ***/
-static int misdn_set_debug(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int level;
 
-	if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
-		return RESULT_SHOWUSAGE; 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn set debug";
+		e->usage =
+			"Usage: misdn set debug <level> [only] | [port <port> [only]]\n"
+			"       Set the debug level of the mISDN channel.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_debug_port(a);
+	}
+
+	if (a->argc < 4 || a->argc > 7)
+		return CLI_SHOWUSAGE;
 
-	level = atoi(argv[3]);
+	level = atoi(a->argv[3]);
 
-	switch (argc) {
+	switch (a->argc) {
 	case 4:	
 	case 5:
 		{
 			int only = 0, i;
-			if (argc == 5) {
-				if (strncasecmp(argv[4], "only", strlen(argv[4])))
-					return RESULT_SHOWUSAGE;
+			if (a->argc == 5) {
+				if (strncasecmp(a->argv[4], "only", strlen(a->argv[4])))
+					return CLI_SHOWUSAGE;
 				else
 					only = 1;
 			}
@@ -761,138 +776,193 @@ static int misdn_set_debug(int fd, int argc, char *argv[])
 				misdn_debug[i] = level;
 				misdn_debug_only[i] = only;
 			}
-			ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
+			ast_cli(a->fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
 		}
 		break;
 	case 6: 
 	case 7:
 		{
 			int port;
-			if (strncasecmp(argv[4], "port", strlen(argv[4])))
-				return RESULT_SHOWUSAGE;
-			port = atoi(argv[5]);
+			if (strncasecmp(a->argv[4], "port", strlen(a->argv[4])))
+				return CLI_SHOWUSAGE;
+			port = atoi(a->argv[5]);
 			if (port <= 0 || port > max_ports) {
 				switch (max_ports) {
 				case 0:
-					ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
+					ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
 					break;
 				case 1:
-					ast_cli(fd, "port number not valid! only port 1 is availble.\n");
+					ast_cli(a->fd, "port number not valid! only port 1 is availble.\n");
 					break;
 				default:
-					ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
+					ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
 				}
 				return 0;
 			}
-			if (argc == 7) {
-				if (strncasecmp(argv[6], "only", strlen(argv[6])))
-					return RESULT_SHOWUSAGE;
+			if (a->argc == 7) {
+				if (strncasecmp(a->argv[6], "only", strlen(a->argv[6])))
+					return CLI_SHOWUSAGE;
 				else
 					misdn_debug_only[port] = 1;
 			} else
 				misdn_debug_only[port] = 0;
 			misdn_debug[port] = level;
-			ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
+			ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
 		}
 	}
-	return 0;
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_set_crypt_debug(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_set_crypt_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 5)
-		return RESULT_SHOWUSAGE; 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn set crypt debug";
+		e->usage =
+			"Usage: misdn set crypt debug <level>\n"
+			"       Set the crypt debug level of the mISDN channel. Level\n"
+			"       must be 1 or 2.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	return 0;
-}
+	if (a->argc != 5)
+		return CLI_SHOWUSAGE;
 
+	/* Is this supposed to not do anything? */
 
-static int misdn_port_block(int fd, int argc, char *argv[])
+	return CLI_SUCCESS;
+}
+
+static char *handle_cli_misdn_port_block(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int port;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn port block";
+		e->usage =
+			"Usage: misdn port block <port>\n"
+			"       Block the specified port by <port>.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
-	port = atoi(argv[3]);
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	misdn_lib_port_block(port);
+	misdn_lib_port_block(atoi(a->argv[3]));
 
-	return 0;
+	return CLI_SUCCESS;
 }
 
-static int misdn_port_unblock(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_port_unblock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int port;
-  
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
-	port = atoi(argv[3]);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn port unblock";
+		e->usage =
+			"Usage: misdn port unblock <port>\n"
+			"       Unblock the port specified by <port>.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	misdn_lib_port_unblock(port);
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	return 0;
-}
+	misdn_lib_port_unblock(atoi(a->argv[3]));
 
+	return CLI_SUCCESS;
+}
 
-static int misdn_restart_port (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_restart_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int port;
-  
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
-	port = atoi(argv[3]);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn restart port";
+		e->usage =
+			"Usage: misdn restart port <port>\n"
+			"       Restart the given port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	misdn_lib_port_restart(port);
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	return 0;
+	misdn_lib_port_restart(atoi(a->argv[3]));
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_restart_pid (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_restart_pid(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int pid;
-  
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
-	pid = atoi(argv[3]);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn restart pid";
+		e->usage =
+			"Usage: misdn restart pid <pid>\n"
+			"       Restart the given pid\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	misdn_lib_pid_restart(pid);
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
 
-	return 0;
+	misdn_lib_pid_restart(atoi(a->argv[3]));
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_port_up (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_port_up(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int port;
-	
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-	
-	port = atoi(argv[3]);
-	
-	misdn_lib_get_port_up(port);
-  
-	return 0;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn port up";
+		e->usage =
+			"Usage: misdn port up <port>\n"
+			"       Try to establish L1 on the given port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	misdn_lib_get_port_up(atoi(a->argv[3]));
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_port_down (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_port_down(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int port;
-	
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-	
-	port = atoi(argv[3]);
-	
-	misdn_lib_get_port_down(port);
-  
-	return 0;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn port down";
+		e->usage =
+			"Usage: misdn port down <port>\n"
+			"       Try to deacivate the L1 on the given port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	misdn_lib_get_port_down(atoi(a->argv[3]));
+
+	return CLI_SUCCESS;
 }
 
-static inline void show_config_description (int fd, enum misdn_cfg_elements elem)
+static inline void show_config_description(int fd, enum misdn_cfg_elements elem)
 {
 	char section[BUFFERSIZE];
 	char name[BUFFERSIZE];
@@ -913,9 +983,11 @@ static inline void show_config_description (int fd, enum misdn_cfg_elements elem
 		ast_cli(fd, "[%s] %s   (Default: %s)\n\t%s\n", section, name, def, desc);
 	else
 		ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
+
+	return;
 }
 
-static int misdn_show_config (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char buffer[BUFFERSIZE];
 	enum misdn_cfg_elements elem;
@@ -923,75 +995,83 @@ static int misdn_show_config (int fd, int argc, char *argv[])
 	int onlyport = -1;
 	int ok = 0;
 
-	if (argc >= 4) {
-		if (!strcmp(argv[3], "description")) {
-			if (argc == 5) {
-				enum misdn_cfg_elements elem = misdn_cfg_get_elem(argv[4]);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn show config";
+		e->usage =
+			"Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
+	        "       Use 0 for <port> to only print the general config.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_show_config(a);
+	}
+
+	if (a->argc >= 4) {
+		if (!strcmp(a->argv[3], "description")) {
+			if (a->argc == 5) {
+				enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]);
 				if (elem == MISDN_CFG_FIRST)
-					ast_cli(fd, "Unknown element: %s\n", argv[4]);
+					ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]);
 				else
-					show_config_description(fd, elem);
-				return 0;
+					show_config_description(a->fd, elem);
+				return CLI_SUCCESS;
 			}
-			return RESULT_SHOWUSAGE;
-		}
-		if (!strcmp(argv[3], "descriptions")) {
-			if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) {
+			return CLI_SHOWUSAGE;
+		} else if (!strcmp(a->argv[3], "descriptions")) {
+			if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) {
 				for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
-					show_config_description(fd, elem);
-					ast_cli(fd, "\n");
+					show_config_description(a->fd, elem);
+					ast_cli(a->fd, "\n");
 				}
 				ok = 1;
 			}
-			if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) {
+			if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) {
 				for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
-					show_config_description(fd, elem);
-					ast_cli(fd, "\n");
+					show_config_description(a->fd, elem);
+					ast_cli(a->fd, "\n");
 				}
 				ok = 1;
 			}
-			return ok ? 0 : RESULT_SHOWUSAGE;
-		}
-		if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) {
-			ast_cli(fd, "Unknown option: %s\n", argv[3]);
-			return RESULT_SHOWUSAGE;
+			return ok ? CLI_SUCCESS : CLI_SHOWUSAGE;
+		} else if (!sscanf(a->argv[3], "%d", &onlyport) || onlyport < 0) {
+			ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]);
+			return CLI_SHOWUSAGE;
 		}
-	}
-	
-	if (argc == 3 || onlyport == 0) {
-		ast_cli(fd,"Misdn General-Config: \n"); 
+	} else if (a->argc == 3 || onlyport == 0) {
+		ast_cli(a->fd, "mISDN General-Config:\n");
 		for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
 			misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer));
-			ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
+			ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
 		}
-		ast_cli(fd, "\n");
+		ast_cli(a->fd, "\n");
 	}
 
 	if (onlyport < 0) {
 		int port = misdn_cfg_get_next_port(0);
 		for (; port > 0; port = misdn_cfg_get_next_port(port)) {
-			ast_cli(fd, "\n[PORT %d]\n", port);
+			ast_cli(a->fd, "\n[PORT %d]\n", port);
 			for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
 				misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer));
-				ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
+				ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
 			}	
-			ast_cli(fd, "\n");
+			ast_cli(a->fd, "\n");
 		}
 	}
 	
 	if (onlyport > 0) {
 		if (misdn_cfg_is_port_valid(onlyport)) {
-			ast_cli(fd, "[PORT %d]\n", onlyport);
+			ast_cli(a->fd, "[PORT %d]\n", onlyport);
 			for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
 				misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer));
-				ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
+				ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
 			}	
-			ast_cli(fd, "\n");
+			ast_cli(a->fd, "\n");
 		} else {
-			ast_cli(fd, "Port %d is not active!\n", onlyport);
+			ast_cli(a->fd, "Port %d is not active!\n", onlyport);
 		}
 	}
-	return 0;
+
+	return CLI_SUCCESS;
 }
 
 struct state_struct {
@@ -1064,11 +1144,26 @@ static void reload_config(void)
 	}
 }
 
-static int misdn_reload (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	ast_cli(fd, "Reloading mISDN Config\n");
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn reload";
+		e->usage =
+			"Usage: misdn reload\n"
+			"       Reload internal mISDN config, read from the config\n"
+			"       file.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 2)
+		return CLI_SHOWUSAGE;
+
+	ast_cli(a->fd, "Reloading mISDN configuration\n");
 	reload_config();
-	return 0;
+	return CLI_SUCCESS;
 }
 
 static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
@@ -1126,27 +1221,42 @@ static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel
 
 }
 
-static int misdn_show_cls(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct chan_list *help = cl_te;
+	struct chan_list *help = NULL;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn show channels";
+		e->usage =
+			"Usage: misdn show channels\n"
+			"       Show the internal mISDN channel list\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+
+	help = cl_te;
   
-	ast_cli(fd, "Chan List: %p\n", cl_te); 
+	ast_cli(a->fd, "Channel List: %p\n", cl_te); 
   
 	for (; help; help = help->next) {
 		struct misdn_bchannel *bc = help->bc;   
 		struct ast_channel *ast = help->ast;
 		if (misdn_debug[0] > 2)
-			ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
+			ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast);
 		if (bc) {
-			print_bc_info(fd, help, bc);
+			print_bc_info(a->fd, help, bc);
 		} else {
 			if (help->state == MISDN_HOLDED) {
-				ast_cli(fd, "ITS A HOLDED BC:\n");
-				ast_cli(fd, " --> l3_id: %x\n"
+				ast_cli(a->fd, "ITS A HOLDED BC:\n");
+				ast_cli(a->fd, " --> l3_id: %x\n"
 						" --> dad:%s oad:%s\n"
 						" --> hold_port: %d\n"
 						" --> hold_channel: %d\n",
-				
 						help->l3id,
 						ast->exten,
 						ast->cid.cid_num,
@@ -1154,178 +1264,261 @@ static int misdn_show_cls(int fd, int argc, char *argv[])
 						help->hold_info.channel
 						);
 			} else {
-				ast_cli(fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
+				ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
 			}
 		}
 	}
 
  	misdn_dump_chanlist();
-	return 0;
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_show_cl (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct chan_list *help=cl_te;
+	struct chan_list *help = NULL;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn show channel";
+		e->usage =
+			"Usage: misdn show channel <channel>\n"
+			"       Show an internal mISDN channel\n.";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_ch(a);
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	help = cl_te;
 
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
 	for (; help; help = help->next) {
 		struct misdn_bchannel *bc = help->bc;   
 		struct ast_channel *ast = help->ast;
     
 		if (bc && ast) {
-			if (!strcasecmp(ast->name, argv[3])) {
-				print_bc_info(fd, help, bc);
+			if (!strcasecmp(ast->name, a->argv[3])) {
+				print_bc_info(a->fd, help, bc);
 				break; 
 			}
 		} 
 	}
-  
-  
-	return 0;
+
+	return CLI_SUCCESS;
 }
 
 ast_mutex_t lock;
 int MAXTICS = 8;
 
-static int misdn_set_tics (int fd, int argc, char *argv[])
+static char *handle_cli_misdn_set_tics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
-	MAXTICS = atoi(argv[3]);
-  
-	return 0;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn set tics";
+		e->usage =
+			"Usage: misdn set tics <value>\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	MAXTICS = atoi(a->argv[3]);
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_show_stacks(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_show_stacks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int port;
 
-	ast_cli(fd, "BEGIN STACK_LIST:\n");
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn show stacks";
+		e->usage =
+			"Usage: misdn show stacks\n"
+			"       Show internal mISDN stack_list.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
 
+	ast_cli(a->fd, "BEGIN STACK_LIST:\n");
 	for (port = misdn_cfg_get_next_port(0); port > 0;
 	     port = misdn_cfg_get_next_port(port)) {
 		char buf[128];
 		get_show_stack_details(port, buf);
-		ast_cli(fd,"  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
+		ast_cli(a->fd,"  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
 	}
 
-	return 0;
+	return CLI_SUCCESS;
 }
 
-
-static int misdn_show_ports_stats(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_show_ports_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int port;
 
-	ast_cli(fd, "Port\tin_calls\tout_calls\n");
-	
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn show ports stats";
+		e->usage =
+			"Usage: misdn show ports stats\n"
+			"       Show mISDNs channel's call statistics per port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	ast_cli(a->fd, "Port\tin_calls\tout_calls\n");
 	for (port = misdn_cfg_get_next_port(0); port > 0;
 	     port = misdn_cfg_get_next_port(port)) {
-		ast_cli(fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
+		ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
 	}
-	ast_cli(fd, "\n");
+	ast_cli(a->fd, "\n");
 
-	return 0;
+	return CLI_SUCCESS;
 }
 
-
-static int misdn_show_port(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_show_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int port;
 	char buf[128];
-	
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-  
-	port = atoi(argv[3]);
-  
-	ast_cli(fd, "BEGIN STACK_LIST:\n");
 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn show port";
+		e->usage =
+			"Usage: misdn show port <port>\n"
+			"       Show detailed information for given port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	port = atoi(a->argv[3]);
+  
+	ast_cli(a->fd, "BEGIN STACK_LIST:\n");
 	get_show_stack_details(port, buf);
-	ast_cli(fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
+	ast_cli(a->fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
 
-	
-	return 0;
+	return CLI_SUCCESS;
 }
 
-static int misdn_send_cd(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_send_calldeflect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char *channame; 
 	char *nr;
 	struct chan_list *tmp;
-  
-	if (argc != 5)
-		return RESULT_SHOWUSAGE;
-  
-	channame = argv[3];
-	nr = argv[4];
 
-	ast_cli(fd, "Sending Calldeflection (%s) to %s\n", nr, channame);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn send calldeflect";
+		e->usage =
+			"Usage: misdn send calldeflect <channel> \"<nr>\"\n"
+			"       Send CallDeflection to mISDN Channel.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_ch(a);
+	}
+
+	if (a->argc != 5)
+		return CLI_SHOWUSAGE;
+
+	channame = a->argv[3];
+	nr = a->argv[4];
+
+	ast_cli(a->fd, "Sending Calldeflection (%s) to %s\n", nr, channame);
 	
 	tmp = get_chan_by_ast_name(channame);
 	if (!tmp) {
-		ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame);
-		return 0; 
+		ast_cli(a->fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
+		return CLI_SUCCESS;
 	}
 
 	if (strlen(nr) >= 15) {
-		ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
-		return 0; 
+		ast_cli(a->fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n", nr, channame);
+		return CLI_SUCCESS;
 	}
 	tmp->bc->fac_out.Function = Fac_CD;
 	ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
 	misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
 
-	return 0; 
+	return CLI_SUCCESS;
 }
 
-static int misdn_send_restart(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_send_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int port;
-	int channel;
-	
-	if ( (argc < 4) ||  (argc >  5) )
-		return RESULT_SHOWUSAGE;
-  
-	port = atoi(argv[3]);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn send restart";
+		e->usage =
+			"Usage: misdn send restart [port [channel]]\n"
+			"       Send a restart for every bchannel on the given port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	if (argc==5) {
-		channel = atoi(argv[4]);
- 		misdn_lib_send_restart(port, channel);
-	} else
- 		misdn_lib_send_restart(port, -1 );
-	
-	return 0;
+	if (a->argc < 4 || a->argc > 5)
+		return CLI_SHOWUSAGE;
+
+	if (a->argc == 5)
+ 		misdn_lib_send_restart(atoi(a->argv[3]), atoi(a->argv[4]));
+	else
+ 		misdn_lib_send_restart(atoi(a->argv[3]), -1);
+
+	return CLI_SUCCESS;
 }
 
-static int misdn_send_digit(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char *channame; 
 	char *msg; 
 	struct chan_list *tmp;
 	int i, msglen;
 
-	if (argc != 5)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn send digit";
+		e->usage =
+			"Usage: misdn send digit <channel> \"<msg>\" \n"
+			"       Send <digit> to <channel> as DTMF Tone\n"
+			"       when channel is a mISDN channel\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_ch(a);
+	}
+
+	if (a->argc != 5)
+		return CLI_SHOWUSAGE;
 
-	channame = argv[3];
-	msg = argv[4];
+	channame = a->argv[3];
+	msg = a->argv[4];
 	msglen = strlen(msg);
 
-	ast_cli(fd, "Sending %s to %s\n", msg, channame);
+	ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
 
 	tmp = get_chan_by_ast_name(channame);
-
 	if (!tmp) {
-		ast_cli(fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
-		return 0; 
+		ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
+		return CLI_SUCCESS; 
 	}
 #if 1
 	for (i = 0; i < msglen; i++) {
-		ast_cli(fd, "Sending: %c\n", msg[i]);
+		ast_cli(a->fd, "Sending: %c\n", msg[i]);
 		send_digit_to_chan(tmp, msg[i]);
 		/* res = ast_safe_sleep(tmp->ast, 250); */
 		usleep(250000);
@@ -1335,26 +1528,36 @@ static int misdn_send_digit(int fd, int argc, char *argv[])
 	ast_dtmf_stream(tmp->ast, NULL, msg, 250);
 #endif
 
-	return 0; 
+	return CLI_SUCCESS;
 }
 
-static int misdn_toggle_echocancel(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_toggle_echocancel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char *channame;
 	struct chan_list *tmp;
 
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-	
-	channame = argv[3];
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn toggle echocancel";
+		e->usage =
+			"Usage: misdn toggle echocancel <channel>\n"
+			"       Toggle EchoCancel on mISDN Channel.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_ch(a);
+	}
+
+	if (a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	channame = a->argv[3];
   
-	ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
+	ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame);
   
 	tmp = get_chan_by_ast_name(channame);
-    
 	if (!tmp) {
-		ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
-		return 0; 
+		ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
+		return CLI_SUCCESS;
 	}
 
 	tmp->toggle_ec = tmp->toggle_ec?0:1;
@@ -1370,45 +1573,57 @@ static int misdn_toggle_echocancel(int fd, int argc, char *argv[])
 		manager_ec_disable(tmp->bc);
 	}
 
-	return 0; 
+	return CLI_SUCCESS;
 }
 
-static int misdn_send_display(int fd, int argc, char *argv[])
+static char *handle_cli_misdn_send_display(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	char *channame; 
-	char *msg; 
+	char *channame;
+	char *msg;
 	struct chan_list *tmp;
 
-	if (argc != 5)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "misdn send display";
+		e->usage =
+			"Usage: misdn send display <channel> \"<msg>\" \n"
+			"       Send <msg> to <channel> as Display Message\n"
+			"       when channel is a mISDN channel\n";
+		return NULL;
+	case CLI_GENERATE:
+		return complete_ch(a);
+	}
+
+	if (a->argc != 5)
+		return CLI_SHOWUSAGE;
 
-	channame = argv[3];
-	msg = argv[4];
+	channame = a->argv[3];
+	msg = a->argv[4];
 
-	ast_cli(fd, "Sending %s to %s\n", msg, channame);
+	ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
 	tmp = get_chan_by_ast_name(channame);
     
 	if (tmp && tmp->bc) {
 		ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
 		misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
 	} else {
-		ast_cli(fd, "No such channel %s\n", channame);
-		return RESULT_FAILURE;
+		ast_cli(a->fd, "No such channel %s\n", channame);
+		return CLI_SUCCESS;
 	}
 
-	return RESULT_SUCCESS ;
+	return CLI_SUCCESS;
 }
 
-static char *complete_ch_helper(const char *line, const char *word, int pos, int state, int rpos)
+static char *complete_ch_helper(struct ast_cli_args *a, int rpos)
 {
 	struct ast_channel *c;
 	int which = 0;
 	char *ret;
-	if (pos != rpos)
+	if (a->pos != rpos)
 		return NULL;
 	for (c = ast_channel_walk_locked(NULL); c; c = ast_channel_walk_locked(c)) {
-		if (!strncasecmp(word, c->name, strlen(word))) {
-			if (++which > state)
+		if (!strncasecmp(a->word, c->name, strlen(a->word))) {
+			if (++which > a->n)
 				break;
 		}
 		ast_mutex_unlock(&c->lock);
@@ -1421,69 +1636,69 @@ static char *complete_ch_helper(const char *line, const char *word, int pos, int
 	return ret;
 }
 
-static char *complete_ch(const char *line, const char *word, int pos, int state)
+static char *complete_ch(struct ast_cli_args *a)
 {
-	return complete_ch_helper(line, word, pos, state, 3);
+	return complete_ch_helper(a, 3);
 }
 
-static char *complete_debug_port (const char *line, const char *word, int pos, int state)
+static char *complete_debug_port (struct ast_cli_args *a)
 {
-	if (state)
+	if (a->n)
 		return NULL;
 
-	switch (pos) {
+	switch (a->pos) {
 	case 4:
-		if (*word == 'p')
+		if (a->word[0] == 'p')
 			return ast_strdup("port");
-		else if (*word == 'o')
+		else if (a->word[0] == 'o')
 			return ast_strdup("only");
 		break;
 	case 6:
-		if (*word == 'o')
+		if (a->word[0] == 'o')
 			return ast_strdup("only");
 		break;
 	}
 	return NULL;
 }
 
-static char *complete_show_config (const char *line, const char *word, int pos, int state)
+static char *complete_show_config(struct ast_cli_args *a)
 {
 	char buffer[BUFFERSIZE];
 	enum misdn_cfg_elements elem;
-	int wordlen = strlen(word);
+	int wordlen = strlen(a->word);
 	int which = 0;
 	int port = 0;
 
-	switch (pos) {
+	switch (a->pos) {
 	case 3:
-		if ((!strncmp(word, "description", wordlen)) && (++which > state))
+		if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n))
 			return ast_strdup("description");
-		if ((!strncmp(word, "descriptions", wordlen)) && (++which > state))
+		if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n))
 			return ast_strdup("descriptions");
-		if ((!strncmp(word, "0", wordlen)) && (++which > state))
+		if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n))
 			return ast_strdup("0");
 		while ((port = misdn_cfg_get_next_port(port)) != -1) {
 			snprintf(buffer, sizeof(buffer), "%d", port);
-			if ((!strncmp(word, buffer, wordlen)) && (++which > state)) {
+			if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) {
 				return ast_strdup(buffer);
 			}
 		}
 		break;
 	case 4:
-		if (strstr(line, "description ")) {
+		if (strstr(a->line, "description ")) {
 			for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
 				if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST))
 					continue;
 				misdn_cfg_get_name(elem, buffer, sizeof(buffer));
-				if (!wordlen || !strncmp(word, buffer, wordlen)) {
-					if (++which > state)
+				if (!wordlen || !strncmp(a->word, buffer, wordlen)) {
+					if (++which > a->n)
 						return ast_strdup(buffer);
 				}
 			}
-		} else if (strstr(line, "descriptions ")) {
-			if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state))
+		} else if (strstr(a->line, "descriptions ")) {
+			if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n))
 				return ast_strdup("general");
-			if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state))
+			if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n))
 				return ast_strdup("ports");
 		}
 		break;
@@ -1492,54 +1707,27 @@ static char *complete_show_config (const char *line, const char *word, int pos,
 }
 
 static struct ast_cli_entry chan_misdn_clis[] = {
-	{ {"misdn","send","calldeflect", NULL}, misdn_send_cd, "Sends CallDeflection to mISDN Channel",
-		"Usage: misdn send calldeflect <channel> \"<nr>\" \n", complete_ch },
-	{ {"misdn","send","digit", NULL}, misdn_send_digit,	"Sends DTMF Digit to mISDN Channel",
-		"Usage: misdn send digit <channel> \"<msg>\" \n"
-		"       Send <digit> to <channel> as DTMF Tone\n"
-		"       when channel is a mISDN channel\n", complete_ch },
-	{ {"misdn","toggle","echocancel", NULL}, misdn_toggle_echocancel, "Toggles EchoCancel on mISDN Channel",
-		"Usage: misdn toggle echocancel <channel>\n", complete_ch },
-	{ {"misdn","send","display", NULL}, misdn_send_display, "Sends Text to mISDN Channel", 
-		"Usage: misdn send display <channel> \"<msg>\" \n"
-		"       Send <msg> to <channel> as Display Message\n"
-		"       when channel is a mISDN channel\n", complete_ch },
-	{ {"misdn","show","config", NULL}, misdn_show_config, "Shows internal mISDN config, read from cfg-file",
-		"Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
-		"       Use 0 for <port> to only print the general config.\n", complete_show_config },
-	{ {"misdn","reload", NULL}, misdn_reload, "Reloads internal mISDN config, read from cfg-file",
-		"Usage: misdn reload\n" },
-	{ {"misdn","set","tics", NULL}, misdn_set_tics, "", 
-		"\n" },
-	{ {"misdn","show","channels", NULL}, misdn_show_cls, "Shows internal mISDN chan_list",
-		"Usage: misdn show channels\n" },
-	{ {"misdn","show","channel", NULL}, misdn_show_cl, "Shows internal mISDN chan_list",
-		"Usage: misdn show channels\n", complete_ch },
-	{ {"misdn","port","block", NULL}, misdn_port_block, "Blocks the given port",
-		"Usage: misdn port block\n" },
-	{ {"misdn","port","unblock", NULL}, misdn_port_unblock, "Unblocks the given port",
-		"Usage: misdn port unblock\n" },
-	{ {"misdn","restart","port", NULL}, misdn_restart_port, "Restarts the given port",
-		"Usage: misdn restart port\n" },
-	{ {"misdn","send","restart", NULL},  misdn_send_restart, 
-	  "Sends a restart for every bchannel on the given port", 
-	  "Usage: misdn send restart <port>\n"},
-	{ {"misdn","restart","pid", NULL}, misdn_restart_pid, "Restarts the given pid",
-		"Usage: misdn restart pid\n" },
-	{ {"misdn","port","up", NULL}, misdn_port_up, "Tries to establish L1 on the given port",
-		"Usage: misdn port up <port>\n" },
-	{ {"misdn","port","down", NULL}, misdn_port_down, "Tries to deacivate the L1 on the given port",
-		"Usage: misdn port down <port>\n" },
-	{ {"misdn","show","stacks", NULL}, misdn_show_stacks, "Shows internal mISDN stack_list",
-		"Usage: misdn show stacks\n" },
-	{ {"misdn","show","ports","stats", NULL}, misdn_show_ports_stats, "Shows chan_misdns call statistics per port",
-		"Usage: misdn show port stats\n" },
-	{ {"misdn","show","port", NULL}, misdn_show_port, "Shows detailed information for given port",
-		"Usage: misdn show port <port>\n" },
-	{ {"misdn","set","debug", NULL}, misdn_set_debug, "Sets Debuglevel of chan_misdn",
-		"Usage: misdn set debug <level> [only] | [port <port> [only]]\n", complete_debug_port },
-	{ {"misdn","set","crypt","debug", NULL}, misdn_set_crypt_debug, "Sets CryptDebuglevel of chan_misdn, at the moment, level={1,2}",
-		"Usage: misdn set crypt debug <level>\n" }
+	NEW_CLI(handle_cli_misdn_port_block,        "Block the given port"),
+	NEW_CLI(handle_cli_misdn_port_down,         "Try to deacivate the L1 on the given port"),
+	NEW_CLI(handle_cli_misdn_port_unblock,      "Unblock the given port"),
+	NEW_CLI(handle_cli_misdn_port_up,           "Try to establish L1 on the given port"),
+	NEW_CLI(handle_cli_misdn_reload,            "Reload internal mISDN config, read from the config file"),
+	NEW_CLI(handle_cli_misdn_restart_pid,       "Restart the given pid"),
+	NEW_CLI(handle_cli_misdn_restart_port,      "Restart the given port"),
+	NEW_CLI(handle_cli_misdn_show_channel,      "Show an internal mISDN channel"),
+	NEW_CLI(handle_cli_misdn_show_channels,     "Show the internal mISDN channel list"),
+	NEW_CLI(handle_cli_misdn_show_config,       "Show internal mISDN config, read from the config file"),
+	NEW_CLI(handle_cli_misdn_show_port,         "Show detailed information for given port"),
+	NEW_CLI(handle_cli_misdn_show_ports_stats,  "Show mISDNs channel's call statistics per port"),
+	NEW_CLI(handle_cli_misdn_show_stacks,       "Show internal mISDN stack_list"),
+	NEW_CLI(handle_cli_misdn_send_calldeflect,  "Send CallDeflection to mISDN Channel"),
+	NEW_CLI(handle_cli_misdn_send_digit,        "Send DTMF digit to mISDN Channel"),
+	NEW_CLI(handle_cli_misdn_send_display,      "Send Text to mISDN Channel"),
+	NEW_CLI(handle_cli_misdn_send_restart,      "Send a restart for every bchannel on the given port"),
+	NEW_CLI(handle_cli_misdn_set_crypt_debug,   "Set CryptDebuglevel of chan_misdn, at the moment, level={1,2}"),
+	NEW_CLI(handle_cli_misdn_set_debug,         "Set Debuglevel of chan_misdn"),
+	NEW_CLI(handle_cli_misdn_set_tics,          "???"),
+	NEW_CLI(handle_cli_misdn_toggle_echocancel, "Toggle EchoCancel on mISDN Channel"),
 };
 
 static int update_config(struct chan_list *ch, int orig) 
diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c
index 6e26e1e4c032249c84a2dabcf8bf7f718f9864f6..cc15725014f663b7ff6fe0251b37754e7cd5566a 100644
--- a/channels/chan_usbradio.c
+++ b/channels/chan_usbradio.c
@@ -1606,77 +1606,134 @@ static struct ast_channel *usbradio_request(const char *type, int format, void *
 	return c;
 }
 
-static int console_key(int fd, int argc, char *argv[])
+static char *handle_cli_radio_key(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct chan_usbradio_pvt *o = find_desc(usbradio_active);
+	struct chan_usbradio_pvt *o = NULL;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "radio key";
+		e->usage =
+			"Usage: radio key\n"
+			"       Simulates COR active.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 2)
+		return CLI_SHOWUSAGE;
 
-	if (argc != 2)
-		return RESULT_SHOWUSAGE; 
+	o = find_desc(usbradio_active);
 	o->txtestkey = 1;
-	return RESULT_SUCCESS;
+
+	return CLI_SUCCESS;
 }
 
-static int console_unkey(int fd, int argc, char *argv[])
+static char *handle_cli_radio_unkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct chan_usbradio_pvt *o = find_desc(usbradio_active);
+	struct chan_usbradio_pvt *o = NULL;
 
-	if (argc != 2)
-		return RESULT_SHOWUSAGE;
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "radio unkey";
+		e->usage =
+			"Usage: radio unkey\n"
+			"       Simulates COR un-active.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 2)
+		return CLI_SHOWUSAGE;
+
+	o = find_desc(usbradio_active);
 	o->txtestkey = 0;
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int radio_tune(int fd, int argc, char *argv[])
+static char *handle_cli_radio_tune(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct chan_usbradio_pvt *o = find_desc(usbradio_active);
-	int i=0;
+	struct chan_usbradio_pvt *o = NULL;
+	int i = 0;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "radio tune [rxnoise|rxvoice|rxtone|rxsquelch|rxcap|rxtracecap|"
+			"txvoice|txtone|txcap|txtracecap|auxvoice|nocap|dump|save]";
+		/* radio tune 6 3000        measured tx value */
+		e->usage =
+			"Usage: radio tune <function>\n"
+			"       rxnoise\n"
+			"       rxvoice\n"
+			"       rxtone\n"
+			"       rxsquelch [newsetting]\n"
+			"       rxcap\n"
+			"       rxtracecap\n"
+			"       txvoice [newsetting]\n"
+			"       txtone [newsetting]\n"
+			"       txcap\n"
+			"       txtracecap\n"
+			"       auxvoice [newsetting]\n"
+			"       nocap\n"
+			"       dump\n"
+			"       save (settings to tuning file)\n"
+			"\n"
+			"       All [newsetting]s are values 0-999\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-	if ((argc < 2) || (argc > 4))
-		return RESULT_SHOWUSAGE; 
+	if ((a->argc < 2) || (a->argc > 4))
+		return CLI_SHOWUSAGE; 
 
-	if (argc == 2) /* just show stuff */
+	if (a->argc == 2) /* just show stuff */
 	{
-		ast_cli(fd,"Output A is currently set to ");
-		if(o->txmixa==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
-		else if (o->txmixa==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
-		else if (o->txmixa==TX_OUT_LSD)ast_cli(fd,"tone.\n");
-		else if (o->txmixa==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
-		else ast_cli(fd,"off.\n");
-
-		ast_cli(fd,"Output B is currently set to ");
-		if(o->txmixb==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
-		else if (o->txmixb==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
-		else if (o->txmixb==TX_OUT_LSD)ast_cli(fd,"tone.\n");
-		else if (o->txmixb==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
-		else ast_cli(fd,"off.\n");
-
-		ast_cli(fd,"Tx Voice Level currently set to %d\n",o->txmixaset);
-		ast_cli(fd,"Tx Tone Level currently set to %d\n",o->txctcssadj);
-		ast_cli(fd,"Rx Squelch currently set to %d\n",o->rxsquelchadj);
-		return RESULT_SHOWUSAGE;
-	}
-
-	if (!strcasecmp(argv[2],"rxnoise")) tune_rxinput(o);
-	else if (!strcasecmp(argv[2],"rxvoice")) tune_rxvoice(o);
-	else if (!strcasecmp(argv[2],"rxtone")) tune_rxctcss(o);
-	else if (!strcasecmp(argv[2],"rxsquelch"))
+		ast_cli(a->fd,"Output A is currently set to ");
+		if(o->txmixa==TX_OUT_COMPOSITE)ast_cli(a->fd,"composite.\n");
+		else if (o->txmixa==TX_OUT_VOICE)ast_cli(a->fd,"voice.\n");
+		else if (o->txmixa==TX_OUT_LSD)ast_cli(a->fd,"tone.\n");
+		else if (o->txmixa==TX_OUT_AUX)ast_cli(a->fd,"auxvoice.\n");
+		else ast_cli(a->fd,"off.\n");
+
+		ast_cli(a->fd,"Output B is currently set to ");
+		if(o->txmixb==TX_OUT_COMPOSITE)ast_cli(a->fd,"composite.\n");
+		else if (o->txmixb==TX_OUT_VOICE)ast_cli(a->fd,"voice.\n");
+		else if (o->txmixb==TX_OUT_LSD)ast_cli(a->fd,"tone.\n");
+		else if (o->txmixb==TX_OUT_AUX)ast_cli(a->fd,"auxvoice.\n");
+		else ast_cli(a->fd,"off.\n");
+
+		ast_cli(a->fd,"Tx Voice Level currently set to %d\n",o->txmixaset);
+		ast_cli(a->fd,"Tx Tone Level currently set to %d\n",o->txctcssadj);
+		ast_cli(a->fd,"Rx Squelch currently set to %d\n",o->rxsquelchadj);
+		return CLI_SHOWUSAGE;
+	}
+
+	o = find_desc(usbradio_active);
+
+	if (!strcasecmp(a->argv[2],"rxnoise")) tune_rxinput(o);
+	else if (!strcasecmp(a->argv[2],"rxvoice")) tune_rxvoice(o);
+	else if (!strcasecmp(a->argv[2],"rxtone")) tune_rxctcss(o);
+	else if (!strcasecmp(a->argv[2],"rxsquelch"))
 	{
-		if (argc == 3)
+		if (a->argc == 3)
 		{
-		    ast_cli(fd,"Current Signal Strength is %d\n",((32767-o->pmrChan->rxRssi)*1000/32767));
-		    ast_cli(fd,"Current Squelch setting is %d\n",o->rxsquelchadj);
-			//ast_cli(fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
-		    //ast_cli(fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
+		    ast_cli(a->fd,"Current Signal Strength is %d\n",((32767-o->pmrChan->rxRssi)*1000/32767));
+		    ast_cli(a->fd,"Current Squelch setting is %d\n",o->rxsquelchadj);
+			//ast_cli(a->fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
+		    //ast_cli(a->fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
 		} else {
-			i = atoi(argv[3]);
-			if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
-			ast_cli(fd,"Changed Squelch setting to %d\n",i);
+			i = atoi(a->argv[3]);
+			if ((i < 0) || (i > 999)) return CLI_SHOWUSAGE;
+			ast_cli(a->fd,"Changed Squelch setting to %d\n",i);
 			o->rxsquelchadj = i;
 			*(o->pmrChan->prxSquelchAdjust)= ((999 - i) * 32767) / 1000;
 		}
 	}
-	else if (!strcasecmp(argv[2],"txvoice")) {
+	else if (!strcasecmp(a->argv[2],"txvoice")) {
 		i = 0;
 
 		if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
@@ -1685,87 +1742,87 @@ static int radio_tune(int fd, int argc, char *argv[])
 		{
 			ast_log(LOG_ERROR,"No txvoice output configured.\n");
 		}
-		else if (argc == 3)
+		else if (a->argc == 3)
 		{
 			if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
-				ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
+				ast_cli(a->fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
 			else
-				ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
+				ast_cli(a->fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
 		}
 		else
 		{
-			i = atoi(argv[3]);
-			if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
+			i = atoi(a->argv[3]);
+			if ((i < 0) || (i > 999)) return CLI_SHOWUSAGE;
 
 			if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
 			{
 			 	o->txmixaset=i;
-				ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
+				ast_cli(a->fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
 			}
 			else
 			{
 			 	o->txmixbset=i;   
-				ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
+				ast_cli(a->fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
 			}
 			mixer_write(o);
 			mult_set(o);
-			ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
+			ast_cli(a->fd,"Changed Tx Voice Output setting to %d\n",i);
 		}
 		tune_txoutput(o,i);
 	}
-	else if (!strcasecmp(argv[2],"auxvoice")) {
+	else if (!strcasecmp(a->argv[2],"auxvoice")) {
 		i = 0;
 		if( (o->txmixa!=TX_OUT_AUX) && (o->txmixb!=TX_OUT_AUX))
 		{
 			ast_log(LOG_WARNING,"No auxvoice output configured.\n");
 		}
-		else if (argc == 3)
+		else if (a->argc == 3)
 		{
 			if(o->txmixa==TX_OUT_AUX)
-				ast_cli(fd,"Current auxvoice setting on Channel A is %d\n",o->txmixaset);
+				ast_cli(a->fd,"Current auxvoice setting on Channel A is %d\n",o->txmixaset);
 			else
-				ast_cli(fd,"Current auxvoice setting on Channel B is %d\n",o->txmixbset);
+				ast_cli(a->fd,"Current auxvoice setting on Channel B is %d\n",o->txmixbset);
 		}
 		else
 		{
-			i = atoi(argv[3]);
-			if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
+			i = atoi(a->argv[3]);
+			if ((i < 0) || (i > 999)) return CLI_SHOWUSAGE;
 			if(o->txmixa==TX_OUT_AUX)
 			{
 				o->txmixbset=i;
-				ast_cli(fd,"Changed auxvoice setting on Channel A to %d\n",o->txmixaset);
+				ast_cli(a->fd,"Changed auxvoice setting on Channel A to %d\n",o->txmixaset);
 			}
 			else
 			{
 				o->txmixbset=i;
-				ast_cli(fd,"Changed auxvoice setting on Channel B to %d\n",o->txmixbset);
+				ast_cli(a->fd,"Changed auxvoice setting on Channel B to %d\n",o->txmixbset);
 			}
 			mixer_write(o);
 			mult_set(o);
 		}
 		//tune_auxoutput(o,i);
 	}
-	else if (!strcasecmp(argv[2],"txtone"))
+	else if (!strcasecmp(a->argv[2],"txtone"))
 	{
-		if (argc == 3)
-			ast_cli(fd,"Current Tx CTCSS modulation setting = %d\n",o->txctcssadj);
+		if (a->argc == 3)
+			ast_cli(a->fd,"Current Tx CTCSS modulation setting = %d\n",o->txctcssadj);
 		else
 		{
-			i = atoi(argv[3]);
-			if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
+			i = atoi(a->argv[3]);
+			if ((i < 0) || (i > 999)) return CLI_SHOWUSAGE;
 			o->txctcssadj = i;
 			set_txctcss_level(o);
-			ast_cli(fd,"Changed Tx CTCSS modulation setting to %i\n",i);
+			ast_cli(a->fd,"Changed Tx CTCSS modulation setting to %i\n",i);
 		}
 		o->txtestkey=1;
 		usleep(5000000);
 		o->txtestkey=0;
 	}
-	else if (!strcasecmp(argv[2],"dump")) pmrdump(o);
-	else if (!strcasecmp(argv[2],"nocap")) 
+	else if (!strcasecmp(a->argv[2],"dump")) pmrdump(o);
+	else if (!strcasecmp(a->argv[2],"nocap")) 
 	{
-		ast_cli(fd,"File capture (trace) was rx=%d tx=%d and now off.\n",o->b.rxcap2,o->b.txcap2);
-		ast_cli(fd,"File capture (raw)   was rx=%d tx=%d and now off.\n",o->b.rxcapraw,o->b.txcapraw);
+		ast_cli(a->fd,"File capture (trace) was rx=%d tx=%d and now off.\n",o->b.rxcap2,o->b.txcap2);
+		ast_cli(a->fd,"File capture (raw)   was rx=%d tx=%d and now off.\n",o->b.rxcapraw,o->b.txcapraw);
 		o->b.rxcapraw=o->b.txcapraw=o->b.rxcap2=o->b.txcap2=o->pmrChan->b.rxCapture=o->pmrChan->b.txCapture=0;
 		if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
 		if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
@@ -1774,37 +1831,37 @@ static int radio_tune(int fd, int argc, char *argv[])
 		if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
 		if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
 	}
-	else if (!strcasecmp(argv[2],"rxtracecap")) 
+	else if (!strcasecmp(a->argv[2],"rxtracecap")) 
 	{
 		if (!frxcaptrace) frxcaptrace= fopen(RX_CAP_TRACE_FILE,"w");
-		ast_cli(fd,"Trace rx on.\n");
+		ast_cli(a->fd,"Trace rx on.\n");
 		o->b.rxcap2=o->pmrChan->b.rxCapture=1;
 	}
-	else if (!strcasecmp(argv[2],"txtracecap")) 
+	else if (!strcasecmp(a->argv[2],"txtracecap")) 
 	{
 		if (!ftxcaptrace) ftxcaptrace= fopen(TX_CAP_TRACE_FILE,"w");
-		ast_cli(fd,"Trace tx on.\n");
+		ast_cli(a->fd,"Trace tx on.\n");
 		o->b.txcap2=o->pmrChan->b.txCapture=1;
 	}
-	else if (!strcasecmp(argv[2],"rxcap")) 
+	else if (!strcasecmp(a->argv[2],"rxcap")) 
 	{
 		if (!frxcapraw) frxcapraw = fopen(RX_CAP_RAW_FILE,"w");
-		ast_cli(fd,"cap rx raw on.\n");
+		ast_cli(a->fd,"cap rx raw on.\n");
 		o->b.rxcapraw=1;
 	}
-	else if (!strcasecmp(argv[2],"txcap")) 
+	else if (!strcasecmp(a->argv[2],"txcap")) 
 	{
 		if (!ftxcapraw) ftxcapraw = fopen(TX_CAP_RAW_FILE,"w");
-		ast_cli(fd,"cap tx raw on.\n");
+		ast_cli(a->fd,"cap tx raw on.\n");
 		o->b.txcapraw=1;
 	}
-	else if (!strcasecmp(argv[2],"save"))
+	else if (!strcasecmp(a->argv[2],"save"))
 	{
 		tune_write(o);
-		ast_cli(fd,"Saved radio tuning settings to usbradio_tune.conf\n");
+		ast_cli(a->fd,"Saved radio tuning settings to usbradio_tune.conf\n");
 	}
-	else return RESULT_SHOWUSAGE;
-	return RESULT_SUCCESS;
+	else return CLI_SHOWUSAGE;
+	return CLI_SUCCESS;
 }
 
 /*
@@ -1835,68 +1892,41 @@ static int set_txctcss_level(struct chan_usbradio_pvt *o)
 /*
 	CLI debugging on and off
 */
-static int radio_set_debug(int fd, int argc, char *argv[])
+static char *handle_cli_radio_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct chan_usbradio_pvt *o = find_desc(usbradio_active);
-
-	o->debuglevel=1;
-	ast_cli(fd,"usbradio debug on.\n");
+	struct chan_usbradio_pvt *o = NULL;
 
-	return RESULT_SUCCESS;
-}
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "radio set debug [off]";
+		e->usage =
+			"Usage: radio set debug [off]\n"
+			"       Enable/Disable radio debugging.\n";
+	case CLI_GENERATE:
+		return NULL;
+	}
+	if (a->argc < 3 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	if (a->argc == 4 && strncasecmp(a->argv[3], "off", 3))
+		return CLI_SHOWUSAGE;
 
-static int radio_set_debug_off(int fd, int argc, char *argv[])
-{
-	struct chan_usbradio_pvt *o = find_desc(usbradio_active);
+	o = find_desc(usbradio_active);
 
-	o->debuglevel=0;
-	ast_cli(fd,"usbradio debug off.\n");
-	return RESULT_SUCCESS;
-}
+	if (a->argc == 3)
+		o->debuglevel = 1;
+	else
+		o->debuglevel = 0;
 
-static char key_usage[] =
-	"Usage: radio key\n"
-	"       Simulates COR active.\n";
+	ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
 
-static char unkey_usage[] =
-	"Usage: radio unkey\n"
-	"       Simulates COR un-active.\n";
+	return CLI_SUCCESS;
+}
 
-/*
-radio tune 6 3000		measured tx value
-*/
-static char radio_tune_usage[] =
-	"Usage: radio tune <function>\n"
-	"       rxnoise\n"
-	"       rxvoice\n"
-	"       rxtone\n"
-	"       rxsquelch [newsetting]\n"
-	"       txvoice [newsetting]\n"
-	"       txtone [newsetting]\n"
-	"       auxvoice [newsetting]\n"
-	"       save (settings to tuning file)\n"
-	"\n       All [newsetting]'s are values 0-999\n\n";
-					  
 static struct ast_cli_entry cli_usbradio[] = {
-	{ { "radio", "key", NULL },
-	console_key, "Simulate Rx Signal Present",
-	key_usage, NULL, NULL},
-
-	{ { "radio", "unkey", NULL },
-	console_unkey, "Simulate Rx Signal Lusb",
-	unkey_usage, NULL, NULL },
-
-	{ { "radio", "tune", NULL },
-	radio_tune, "Radio Tune",
-	radio_tune_usage, NULL, NULL },
-
-	{ { "radio", "set", "debug", NULL },
-	radio_set_debug, "Radio Debug",
-	radio_tune_usage, NULL, NULL },
-
-	{ { "radio", "set", "debug", "off", NULL },
-	radio_set_debug_off, "Radio Debug",
-	radio_tune_usage, NULL, NULL },
+	NEW_CLI(handle_cli_radio_key,       "Simulate Rx Signal Present"),
+	NEW_CLI(handle_cli_radio_unkey,     "Simulate Rx Signal Lusb"),
+	NEW_CLI(handle_cli_radio_tune,      "Radio Tune"),
+	NEW_CLI(handle_cli_radio_set_debug, "Enable/Disable Radio Debugging"),
 };
 
 /*
diff --git a/codecs/codec_zap.c b/codecs/codec_zap.c
index 8bd87f5fd9844913378aec3499b567d19aa58bcd..1b8a2832dfbb9afca1aac6d9d5f14bc651ec6f70 100644
--- a/codecs/codec_zap.c
+++ b/codecs/codec_zap.c
@@ -67,29 +67,10 @@ static struct channel_usage {
 	int decoders;
 } channels;
 
-static char show_transcoder_usage[] =
-"Usage: show transcoder\n"
-"       Displays channel utilization of Zaptel transcoder(s).\n";
-
-static char transcoder_show_usage[] =
-"Usage: transcoder show\n"
-"       Displays channel utilization of Zaptel transcoder(s).\n";
-
-static int transcoder_show(int fd, int argc, char **argv);
-
-static struct ast_cli_entry cli_deprecated[] = {
-	{ { "show", "transcoder", NULL },
-	  transcoder_show,
-	  "Display Zaptel transcoder utilization.",
-	  show_transcoder_usage}
-};
+static char *handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 static struct ast_cli_entry cli[] = {
-	{ { "transcoder", "show", NULL },
-	  transcoder_show,
-	  "Display Zaptel transcoder utilization.",
-	  transcoder_show_usage, NULL,
-	  &cli_deprecated[0]}
+	NEW_CLI(handle_cli_transcoder_show, "Display Zaptel transcoder utilization.")
 };
 
 struct format_map {
@@ -116,18 +97,32 @@ struct pvt {
 	struct ast_frame f;
 };
 
-static int transcoder_show(int fd, int argc, char **argv)
+static char *handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct channel_usage copy;
 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "transcoder show";
+		e->usage =
+			"Usage: transcoder show\n"
+			"       Displays channel utilization of Zaptel transcoder(s).\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 2)
+		return CLI_SHOWUSAGE;
+
 	copy = channels;
 
 	if (copy.total == 0)
-		ast_cli(fd, "No Zaptel transcoders found.\n");
+		ast_cli(a->fd, "No Zaptel transcoders found.\n");
 	else
-		ast_cli(fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
+		ast_cli(a->fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 static int zap_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
@@ -492,4 +487,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Generic Zaptel Transcode
 		.load = load_module,
 		.unload = unload_module,
 		.reload = reload,
-	       );
+		);
diff --git a/main/config.c b/main/config.c
index 1dc16fdc72f6da1c2f9cb4460e36df684decd001..d8fb6df85f95fd54b192fe3694d7365612f01c6f 100644
--- a/main/config.c
+++ b/main/config.c
@@ -2143,37 +2143,42 @@ int ast_parse_arg(const char *arg, enum ast_parse_flags flags,
 	return error;
 }
 
-static int config_command(int fd, int argc, char **argv) 
+static char *handle_cli_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ast_config_engine *eng;
 	struct ast_config_map *map;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "core show config mappings";
+		e->usage =
+			"Usage: core show config mappings\n"
+			"	Shows the filenames to config engines.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 	
 	ast_mutex_lock(&config_lock);
 
-	ast_cli(fd, "\n\n");
+	ast_cli(a->fd, "\n\n");
 	for (eng = config_engine_list; eng; eng = eng->next) {
-		ast_cli(fd, "\nConfig Engine: %s\n", eng->name);
+		ast_cli(a->fd, "\nConfig Engine: %s\n", eng->name);
 		for (map = config_maps; map; map = map->next)
 			if (!strcasecmp(map->driver, eng->name)) {
-				ast_cli(fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
+				ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
 					map->table ? map->table : map->name);
 			}
 	}
-	ast_cli(fd,"\n\n");
+	ast_cli(a->fd,"\n\n");
 	
 	ast_mutex_unlock(&config_lock);
 
-	return 0;
+	return CLI_SUCCESS;
 }
 
-static char show_config_help[] =
-	"Usage: core show config mappings\n"
-	"	Shows the filenames to config engines.\n";
-
 static struct ast_cli_entry cli_config[] = {
-	{ { "core", "show", "config", "mappings", NULL },
-	config_command, "Display config mappings (file names to config engines)",
-	show_config_help },
+	NEW_CLI(handle_cli_core_show_config_mappings, "Display config mappings (file names to config engines)"),
 };
 
 int register_config_cli() 
diff --git a/main/rtp.c b/main/rtp.c
index 3d2d826e3782cc1262cce79e63855d4ad44627f6..1ae68ef93ae6bb81eca0423e7e02ecc070eda113 100644
--- a/main/rtp.c
+++ b/main/rtp.c
@@ -3801,16 +3801,14 @@ enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel
 	return res;
 }
 
-static int rtp_do_debug_ip(int fd, int argc, char *argv[])
+static char *rtp_do_debug_ip(struct ast_cli_args *a)
 {
 	struct hostent *hp;
 	struct ast_hostent ahp;
 	int port = 0;
 	char *p, *arg;
 
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-	arg = argv[3];
+	arg = a->argv[3];
 	p = strstr(arg, ":");
 	if (p) {
 		*p = '\0';
@@ -3818,29 +3816,29 @@ static int rtp_do_debug_ip(int fd, int argc, char *argv[])
 		port = atoi(p);
 	}
 	hp = ast_gethostbyname(arg, &ahp);
-	if (hp == NULL)
-		return RESULT_SHOWUSAGE;
+	if (hp == NULL) {
+		ast_cli(a->fd, "Lookup failed for '%s'\n", arg);
+		return CLI_FAILURE;
+	}
 	rtpdebugaddr.sin_family = AF_INET;
 	memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr));
 	rtpdebugaddr.sin_port = htons(port);
 	if (port == 0)
-		ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtpdebugaddr.sin_addr));
+		ast_cli(a->fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtpdebugaddr.sin_addr));
 	else
-		ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtpdebugaddr.sin_addr), port);
+		ast_cli(a->fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtpdebugaddr.sin_addr), port);
 	rtpdebug = 1;
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int rtcp_do_debug_ip(int fd, int argc, char *argv[])
+static char *rtcp_do_debug_ip(struct ast_cli_args *a)
 {
 	struct hostent *hp;
 	struct ast_hostent ahp;
 	int port = 0;
 	char *p, *arg;
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
 
-	arg = argv[3];
+	arg = a->argv[3];
 	p = strstr(arg, ":");
 	if (p) {
 		*p = '\0';
@@ -3848,171 +3846,143 @@ static int rtcp_do_debug_ip(int fd, int argc, char *argv[])
 		port = atoi(p);
 	}
 	hp = ast_gethostbyname(arg, &ahp);
-	if (hp == NULL)
-		return RESULT_SHOWUSAGE;
+	if (hp == NULL) {
+		ast_cli(a->fd, "Lookup failed for '%s'\n", arg);
+		return CLI_FAILURE;
+	}
 	rtcpdebugaddr.sin_family = AF_INET;
 	memcpy(&rtcpdebugaddr.sin_addr, hp->h_addr, sizeof(rtcpdebugaddr.sin_addr));
 	rtcpdebugaddr.sin_port = htons(port);
 	if (port == 0)
-		ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr));
+		ast_cli(a->fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr));
 	else
-		ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port);
+		ast_cli(a->fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port);
 	rtcpdebug = 1;
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int rtp_do_debug(int fd, int argc, char *argv[])
+static char *handle_cli_rtp_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 2) {
-		if (argc != 4)
-			return RESULT_SHOWUSAGE;
-		return rtp_do_debug_ip(fd, argc, argv);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "rtp debug [off|ip]";
+		e->usage =
+			"Usage: rtp debug [off]|[ip host[:port]]\n"
+			"       Enable/Disable dumping of all RTP packets. If 'ip' is\n"
+			"       specified, limit the dumped packets to those to and from\n"
+			"       the specified 'host' with optional port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
 	}
-	rtpdebug = 1;
-	memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr));
-	ast_cli(fd, "RTP Debugging Enabled\n");
-	return RESULT_SUCCESS;
-}
-   
-static int rtcp_do_debug(int fd, int argc, char *argv[])
-{
-	if (argc != 2) {
-		if (argc != 4)
-			return RESULT_SHOWUSAGE;
-		return rtcp_do_debug_ip(fd, argc, argv);
+
+	if (a->argc < 2 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	if (a->argc == 2) {
+		rtpdebug = 1;
+		memset(&rtpdebugaddr, 0, sizeof(rtpdebugaddr));
+		ast_cli(a->fd, "RTP Debugging Enabled\n");
+	} else if (a->argc == 3) {
+		if (strncasecmp(a->argv[2], "off", 3))
+			return CLI_SHOWUSAGE;
+		rtpdebug = 0;
+		ast_cli(a->fd, "RTP Debugging Disabled\n");
+	} else {
+		if (strncasecmp(a->argv[2], "ip", 2))
+			return CLI_SHOWUSAGE;
+		return rtp_do_debug_ip(a);
 	}
-	rtcpdebug = 1;
-	memset(&rtcpdebugaddr,0,sizeof(rtcpdebugaddr));
-	ast_cli(fd, "RTCP Debugging Enabled\n");
-	return RESULT_SUCCESS;
-}
 
-static int rtcp_do_stats(int fd, int argc, char *argv[])
-{
-	if (argc != 2)
-		return RESULT_SHOWUSAGE;
-	rtcpstats = 1;
-	ast_cli(fd, "RTCP Stats Enabled\n");
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int rtp_no_debug(int fd, int argc, char *argv[])
+static char *handle_cli_rtcp_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	rtpdebug = 0;
-	ast_cli(fd,"RTP Debugging Disabled\n");
-	return RESULT_SUCCESS;
-}
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "rtcp debug [off|ip]";
+		e->usage =
+			"Usage: rtcp debug [off]|[ip host[:port]]\n"
+			"       Enable/Disable dumping of all RTCP packets. If 'ip' is\n"
+			"       specified, limit the dumped packets to those to and from\n"
+			"       the specified 'host' with optional port.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-static int rtcp_no_debug(int fd, int argc, char *argv[])
-{
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	rtcpdebug = 0;
-	ast_cli(fd,"RTCP Debugging Disabled\n");
-	return RESULT_SUCCESS;
-}
+	if (a->argc < 2 || a->argc > 4)
+		return CLI_SHOWUSAGE;
+	if (a->argc == 2) {
+		rtcpdebug = 1;
+		memset(&rtcpdebugaddr, 0, sizeof(rtcpdebugaddr));
+		ast_cli(a->fd, "RTCP Debugging Enabled\n");
+	} else if (a->argc == 3) {
+		if (strncasecmp(a->argv[2], "off", 3))
+			return CLI_SHOWUSAGE;
+		rtcpdebug = 0;
+		ast_cli(a->fd, "RTCP Debugging Disabled\n");
+	} else {
+		if (strncasecmp(a->argv[2], "ip", 2))
+			return CLI_SHOWUSAGE;
+		return rtcp_do_debug_ip(a);
+	}
 
-static int rtcp_no_stats(int fd, int argc, char *argv[])
-{
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	rtcpstats = 0;
-	ast_cli(fd,"RTCP Stats Disabled\n");
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
-static int stun_do_debug(int fd, int argc, char *argv[])
+static char *handle_cli_rtcp_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	if (argc != 2)
-		return RESULT_SHOWUSAGE;
-	stundebug = 1;
-	ast_cli(fd, "STUN Debugging Enabled\n");
-	return RESULT_SUCCESS;
-}
-   
-static int stun_no_debug(int fd, int argc, char *argv[])
-{
-	if (argc != 3)
-		return RESULT_SHOWUSAGE;
-	stundebug = 0;
-	ast_cli(fd, "STUN Debugging Disabled\n");
-	return RESULT_SUCCESS;
-}
-
-static const char debug_usage[] =
-  "Usage: rtp debug [ip host[:port]]\n"
-  "       Enable dumping of all RTP packets to and from host.\n";
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "rtcp stats [off]";
+		e->usage =
+			"Usage: rtcp stats [off]\n"
+			"       Enable/Disable dumping of RTCP stats.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-static const char no_debug_usage[] =
-  "Usage: rtp debug off\n"
-  "       Disable all RTP debugging\n";
+	if (a->argc < 2 || a->argc > 3)
+		return CLI_SHOWUSAGE;
+	if (a->argc == 3 && strncasecmp(a->argv[2], "off", 3))
+		return CLI_SHOWUSAGE;
 
-static const char stun_debug_usage[] =
-  "Usage: stun debug\n"
-  "       Enable STUN (Simple Traversal of UDP through NATs) debugging\n";
+	rtcpstats = (a->argc == 3) ? 0 : 1;
+	ast_cli(a->fd, "RTCP Stats %s\n", rtcpstats ? "Enabled" : "Disabled");
+	return CLI_SUCCESS;
+}
 
-static const char stun_no_debug_usage[] =
-  "Usage: stun debug off\n"
-  "       Disable STUN debugging\n";
+static char *handle_cli_stun_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "stun debug [off]";
+		e->usage =
+			"Usage: stun debug [off]\n"
+			"       Enable/Disable STUN (Simple Traversal of UDP through NATs)\n"
+			"       debugging\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
 
-static const char rtcp_debug_usage[] =
-  "Usage: rtcp debug [ip host[:port]]\n"
-  "       Enable dumping of all RTCP packets to and from host.\n";
-  
-static const char rtcp_no_debug_usage[] =
-  "Usage: rtcp debug off\n"
-  "       Disable all RTCP debugging\n";
+	if (a->argc < 2 || a->argc > 3)
+		return CLI_SHOWUSAGE;
+	if (a->argc == 3 && strncasecmp(a->argv[2], "off", 3))
+		return CLI_SHOWUSAGE;
 
-static const char rtcp_stats_usage[] =
-  "Usage: rtcp stats\n"
-  "       Enable dumping of RTCP stats.\n";
-  
-static const char rtcp_no_stats_usage[] =
-  "Usage: rtcp stats off\n"
-  "       Disable all RTCP stats\n";
+	stundebug = (a->argc == 3) ? 0 : 1;
+	ast_cli(a->fd, "STUN Debugging %s\n", stundebug ? "Enabled" : "Disabled");
+	return CLI_SUCCESS;
+}
 
 static struct ast_cli_entry cli_rtp[] = {
-	{ { "rtp", "debug", "ip", NULL },
-	rtp_do_debug, "Enable RTP debugging on IP",
-	debug_usage },
-
-	{ { "rtp", "debug", NULL },
-	rtp_do_debug, "Enable RTP debugging",
-	debug_usage },
-
-	{ { "rtp", "debug", "off", NULL },
-	rtp_no_debug, "Disable RTP debugging",
-	no_debug_usage },
-
-	{ { "rtcp", "debug", "ip", NULL },
-	rtcp_do_debug, "Enable RTCP debugging on IP",
-	rtcp_debug_usage },
-
-	{ { "rtcp", "debug", NULL },
-	rtcp_do_debug, "Enable RTCP debugging",
-	rtcp_debug_usage },
-
-	{ { "rtcp", "debug", "off", NULL },
-	rtcp_no_debug, "Disable RTCP debugging",
-	rtcp_no_debug_usage },
-
-	{ { "rtcp", "stats", NULL },
-	rtcp_do_stats, "Enable RTCP stats",
-	rtcp_stats_usage },
-
-	{ { "rtcp", "stats", "off", NULL },
-	rtcp_no_stats, "Disable RTCP stats",
-	rtcp_no_stats_usage },
-
-	{ { "stun", "debug", NULL },
-	stun_do_debug, "Enable STUN debugging",
-	stun_debug_usage },
-
-	{ { "stun", "debug", "off", NULL },
-	stun_no_debug, "Disable STUN debugging",
-	stun_no_debug_usage },
+	NEW_CLI(handle_cli_rtp_debug,  "Enable/Disable RTP debugging"),
+	NEW_CLI(handle_cli_rtcp_debug, "Enable/Disable RTCP debugging"),
+	NEW_CLI(handle_cli_rtcp_stats, "Enable/Disable RTCP stats"),
+	NEW_CLI(handle_cli_stun_debug, "Enable/Disable STUN debugging"),
 };
 
 static int __ast_rtp_reload(int reload)
diff --git a/res/res_config_pgsql.c b/res/res_config_pgsql.c
index ce1174a548b0bf8331353a035253ebff47af0932..2148f741cd867c72e592369ff4fffa7e26426bd7 100644
--- a/res/res_config_pgsql.c
+++ b/res/res_config_pgsql.c
@@ -3,21 +3,21 @@
  *
  * Copyright (C) 1999-2005, Digium, Inc.
  * 
- * Manuel Guesdon <mguesdon@oxymium.net> - Postgresql RealTime Driver Author/Adaptor
+ * Manuel Guesdon <mguesdon@oxymium.net> - PostgreSQL RealTime Driver Author/Adaptor
  * Mark Spencer <markster@digium.com>  - Asterisk Author
  * Matthew Boehm <mboehm@cytelcom.com> - MySQL RealTime Driver Author
  *
- * res_config_pgsql.c <Postgresql plugin for RealTime configuration engine>
+ * res_config_pgsql.c <PostgreSQL plugin for RealTime configuration engine>
  *
  * v1.0   - (07-11-05) - Initial version based on res_config_mysql v2.0
  */
 
 /*! \file
  *
- * \brief Postgresql plugin for Asterisk RealTime Architecture
+ * \brief PostgreSQL plugin for Asterisk RealTime Architecture
  *
  * \author Mark Spencer <markster@digium.com>
- * \author Manuel Guesdon <mguesdon@oxymium.net> - Postgresql RealTime Driver Author/Adaptor
+ * \author Manuel Guesdon <mguesdon@oxymium.net> - PostgreSQL RealTime Driver Author/Adaptor
  *
  * \arg http://www.postgresql.org
  */
@@ -64,16 +64,10 @@ static time_t connect_time = 0;
 
 static int parse_config(int reload);
 static int pgsql_reconnect(const char *database);
-static int realtime_pgsql_status(int fd, int argc, char **argv);
-
-static const char cli_realtime_pgsql_status_usage[] =
-	"Usage: realtime pgsql status\n"
-	"       Shows connection information for the Postgresql RealTime driver\n";
+static char *handle_cli_realtime_pgsql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 static struct ast_cli_entry cli_realtime[] = {
-	{ { "realtime", "pgsql", "status", NULL },
-	realtime_pgsql_status, "Shows connection information for the Postgresql RealTime driver",
-	cli_realtime_pgsql_status_usage },
+	NEW_CLI(handle_cli_realtime_pgsql_status, "Shows connection information for the PostgreSQL RealTime driver"),
 };
 
 static struct ast_variable *realtime_pgsql(const char *database, const char *table, va_list ap)
@@ -88,7 +82,7 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
 	struct ast_variable *var = NULL, *prev = NULL;
 
 	if (!table) {
-		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
 		return NULL;
 	}
 
@@ -97,7 +91,7 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
 	newval = va_arg(ap, const char *);
 	if (!newparam || !newval) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
+				"PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 		if (pgsqlConn) {
 			PQfinish(pgsqlConn);
 			pgsqlConn = NULL;
@@ -131,9 +125,9 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
 
 	if (!(result = PQexec(pgsqlConn, sql))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
 		ast_mutex_unlock(&pgsql_lock);
 		return NULL;
 	} else {
@@ -142,16 +136,16 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
 			&& result_status != PGRES_TUPLES_OK
 			&& result_status != PGRES_NONFATAL_ERROR) {
 			ast_log(LOG_WARNING,
-					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
 						PQresultErrorMessage(result), PQresStatus(result_status));
 			ast_mutex_unlock(&pgsql_lock);
 			return NULL;
 		}
 	}
 
-	ast_debug(1, "1Postgresql RealTime: Result=%p Query: %s\n", result, sql);
+	ast_debug(1, "PostgreSQL RealTime: Result=%p Query: %s\n", result, sql);
 
 	if ((num_rows = PQntuples(result)) > 0) {
 		int i = 0;
@@ -159,7 +153,7 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
 		int numFields = PQnfields(result);
 		char **fieldnames = NULL;
 
-		ast_debug(1, "Postgresql RealTime: Found %d rows.\n", num_rows);
+		ast_debug(1, "PostgreSQL RealTime: Found %d rows.\n", num_rows);
 
 		if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) {
 			ast_mutex_unlock(&pgsql_lock);
@@ -189,7 +183,7 @@ static struct ast_variable *realtime_pgsql(const char *database, const char *tab
 		ast_free(fieldnames);
 	} else {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Could not find any rows in table %s.\n", table);
+				"PostgreSQL RealTime: Could not find any rows in table %s.\n", table);
 	}
 
 	ast_mutex_unlock(&pgsql_lock);
@@ -213,7 +207,7 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
 	struct ast_category *cat = NULL;
 
 	if (!table) {
-		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
 		return NULL;
 	}
 
@@ -225,7 +219,7 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
 	newval = va_arg(ap, const char *);
 	if (!newparam || !newval) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
+				"PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 		if (pgsqlConn) {
 			PQfinish(pgsqlConn);
 			pgsqlConn = NULL;
@@ -273,9 +267,9 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
 
 	if (!(result = PQexec(pgsqlConn, sql))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
 		ast_mutex_unlock(&pgsql_lock);
 		return NULL;
 	} else {
@@ -284,16 +278,16 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
 			&& result_status != PGRES_TUPLES_OK
 			&& result_status != PGRES_NONFATAL_ERROR) {
 			ast_log(LOG_WARNING,
-					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
 						PQresultErrorMessage(result), PQresStatus(result_status));
 			ast_mutex_unlock(&pgsql_lock);
 			return NULL;
 		}
 	}
 
-	ast_debug(1, "2Postgresql RealTime: Result=%p Query: %s\n", result, sql);
+	ast_debug(1, "PostgreSQL RealTime: Result=%p Query: %s\n", result, sql);
 
 	if ((num_rows = PQntuples(result)) > 0) {
 		int numFields = PQnfields(result);
@@ -301,7 +295,7 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
 		int rowIndex = 0;
 		char **fieldnames = NULL;
 
-		ast_debug(1, "Postgresql RealTime: Found %d rows.\n", num_rows);
+		ast_debug(1, "PostgreSQL RealTime: Found %d rows.\n", num_rows);
 
 		if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) {
 			ast_mutex_unlock(&pgsql_lock);
@@ -333,7 +327,7 @@ static struct ast_config *realtime_multi_pgsql(const char *database, const char
 		ast_free(fieldnames);
 	} else {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Could not find any rows in table %s.\n", table);
+				"PostgreSQL RealTime: Could not find any rows in table %s.\n", table);
 	}
 
 	ast_mutex_unlock(&pgsql_lock);
@@ -351,7 +345,7 @@ static int update_pgsql(const char *database, const char *table, const char *key
 	const char *newparam, *newval;
 
 	if (!table) {
-		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
 		return -1;
 	}
 
@@ -360,7 +354,7 @@ static int update_pgsql(const char *database, const char *table, const char *key
 	newval = va_arg(ap, const char *);
 	if (!newparam || !newval) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
+				"PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 		if (pgsqlConn) {
 			PQfinish(pgsqlConn);
 			pgsqlConn = NULL;
@@ -381,7 +375,7 @@ static int update_pgsql(const char *database, const char *table, const char *key
 	snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield,
 			 lookup);
 
-	ast_debug(1, "Postgresql RealTime: Update SQL: %s\n", sql);
+	ast_debug(1, "PostgreSQL RealTime: Update SQL: %s\n", sql);
 
 	/* We now have our complete statement; Lets connect to the server and execute it. */
 	ast_mutex_lock(&pgsql_lock);
@@ -392,9 +386,9 @@ static int update_pgsql(const char *database, const char *table, const char *key
 
 	if (!(result = PQexec(pgsqlConn, sql))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
 		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	} else {
@@ -403,9 +397,9 @@ static int update_pgsql(const char *database, const char *table, const char *key
 			&& result_status != PGRES_TUPLES_OK
 			&& result_status != PGRES_NONFATAL_ERROR) {
 			ast_log(LOG_WARNING,
-					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
 						PQresultErrorMessage(result), PQresStatus(result_status));
 			ast_mutex_unlock(&pgsql_lock);
 			return -1;
@@ -415,7 +409,7 @@ static int update_pgsql(const char *database, const char *table, const char *key
 	numrows = atoi(PQcmdTuples(result));
 	ast_mutex_unlock(&pgsql_lock);
 
-	ast_debug(1, "Postgresql RealTime: Updated %d rows on table: %s\n", numrows, table);
+	ast_debug(1, "PostgreSQL RealTime: Updated %d rows on table: %s\n", numrows, table);
 
 	/* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html
 	 * An integer greater than zero indicates the number of rows affected
@@ -441,7 +435,7 @@ static int store_pgsql(const char *database, const char *table, va_list ap)
 	const char *newparam, *newval;
 
 	if (!table) {
-		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
 		return -1;
 	}
 
@@ -450,7 +444,7 @@ static int store_pgsql(const char *database, const char *table, va_list ap)
 	newval = va_arg(ap, const char *);
 	if (!newparam || !newval) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Realtime storage requires at least 1 parameter and 1 value to store.\n");
+				"PostgreSQL RealTime: Realtime storage requires at least 1 parameter and 1 value to store.\n");
 		if (pgsqlConn) {
 			PQfinish(pgsqlConn);
 			pgsqlConn = NULL;
@@ -481,13 +475,13 @@ static int store_pgsql(const char *database, const char *table, va_list ap)
 	va_end(ap);
 	snprintf(sql, sizeof(sql), "INSERT INTO (%s) VALUES (%s)", params, vals);
 
-	ast_debug(1, "Postgresql RealTime: Insert SQL: %s\n", sql);
+	ast_debug(1, "PostgreSQL RealTime: Insert SQL: %s\n", sql);
 
 	if (!(result = PQexec(pgsqlConn, sql))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
 		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	} else {
@@ -496,9 +490,9 @@ static int store_pgsql(const char *database, const char *table, va_list ap)
 			&& result_status != PGRES_TUPLES_OK
 			&& result_status != PGRES_NONFATAL_ERROR) {
 			ast_log(LOG_WARNING,
-					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
 						PQresultErrorMessage(result), PQresStatus(result_status));
 			ast_mutex_unlock(&pgsql_lock);
 			return -1;
@@ -508,7 +502,7 @@ static int store_pgsql(const char *database, const char *table, va_list ap)
 	insertid = PQoidValue(result);
 	ast_mutex_unlock(&pgsql_lock);
 
-	ast_debug(1, "Postgresql RealTime: row inserted on table: %s, id: %u\n", table, insertid);
+	ast_debug(1, "PostgreSQL RealTime: row inserted on table: %s, id: %u\n", table, insertid);
 
 	/* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html
 	 * An integer greater than zero indicates the number of rows affected
@@ -532,7 +526,7 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke
 	const char *newparam, *newval;
 
 	if (!table) {
-		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		ast_log(LOG_WARNING, "PostgreSQL RealTime: No table specified.\n");
 		return -1;
 	}
 
@@ -542,7 +536,7 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke
 	if (!newparam || !newval) {*/
 	if (ast_strlen_zero(keyfield) || ast_strlen_zero(lookup))  {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Realtime destroy requires at least 1 parameter and 1 value to search on.\n");
+				"PostgreSQL RealTime: Realtime destroy requires at least 1 parameter and 1 value to search on.\n");
 		if (pgsqlConn) {
 			PQfinish(pgsqlConn);
 			pgsqlConn = NULL;
@@ -572,13 +566,13 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke
 	}
 	va_end(ap);
 
-	ast_debug(1, "Postgresql RealTime: Delete SQL: %s\n", sql);
+	ast_debug(1, "PostgreSQL RealTime: Delete SQL: %s\n", sql);
 
 	if (!(result = PQexec(pgsqlConn, sql))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
 		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	} else {
@@ -587,9 +581,9 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke
 			&& result_status != PGRES_TUPLES_OK
 			&& result_status != PGRES_NONFATAL_ERROR) {
 			ast_log(LOG_WARNING,
-					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
 						PQresultErrorMessage(result), PQresStatus(result_status));
 			ast_mutex_unlock(&pgsql_lock);
 			return -1;
@@ -599,7 +593,7 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke
 	numrows = atoi(PQcmdTuples(result));
 	ast_mutex_unlock(&pgsql_lock);
 
-	ast_debug(1, "Postgresql RealTime: Deleted %d rows on table: %s\n", numrows, table);
+	ast_debug(1, "PostgreSQL RealTime: Deleted %d rows on table: %s\n", numrows, table);
 
 	/* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html
 	 * An integer greater than zero indicates the number of rows affected
@@ -631,7 +625,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 	last[0] = '\0';
 
 	if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) {
-		ast_log(LOG_WARNING, "Postgresql RealTime: Cannot configure myself.\n");
+		ast_log(LOG_WARNING, "PostgreSQL RealTime: Cannot configure myself.\n");
 		return NULL;
 	}
 
@@ -639,7 +633,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 	ast_build_string(&sql, &sqlleft, "WHERE filename='%s' and commented=0", file);
 	ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");
 
-	ast_debug(1, "Postgresql RealTime: Static SQL: %s\n", sqlbuf);
+	ast_debug(1, "PostgreSQL RealTime: Static SQL: %s\n", sqlbuf);
 
 	/* We now have our complete statement; Lets connect to the server and execute it. */
 	ast_mutex_lock(&pgsql_lock);
@@ -650,9 +644,9 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 
 	if (!(result = PQexec(pgsqlConn, sqlbuf))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+		ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
 		ast_mutex_unlock(&pgsql_lock);
 		return NULL;
 	} else {
@@ -661,9 +655,9 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 			&& result_status != PGRES_TUPLES_OK
 			&& result_status != PGRES_NONFATAL_ERROR) {
 			ast_log(LOG_WARNING,
-					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
-			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
-			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+					"PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "PostgreSQL RealTime: Query: %s\n", sql);
+			ast_debug(1, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
 						PQresultErrorMessage(result), PQresStatus(result_status));
 			ast_mutex_unlock(&pgsql_lock);
 			return NULL;
@@ -673,7 +667,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 	if ((num_rows = PQntuples(result)) > 0) {
 		int rowIndex = 0;
 
-		ast_debug(1, "Postgresql RealTime: Found %ld rows.\n", num_rows);
+		ast_debug(1, "PostgreSQL RealTime: Found %ld rows.\n", num_rows);
 
 		for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
 			char *field_category = PQgetvalue(result, rowIndex, 0);
@@ -702,7 +696,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table,
 		}
 	} else {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Could not find config '%s' in database.\n", file);
+				"PostgreSQL RealTime: Could not find config '%s' in database.\n", file);
 	}
 
 	PQclear(result);
@@ -727,7 +721,7 @@ static int load_module(void)
 		return AST_MODULE_LOAD_DECLINE;
 
 	ast_config_engine_register(&pgsql_engine);
-	ast_verb(1, "Postgresql RealTime driver loaded.\n");
+	ast_verb(1, "PostgreSQL RealTime driver loaded.\n");
 	ast_cli_register_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
 
 	return 0;
@@ -744,7 +738,7 @@ static int unload_module(void)
 	}
 	ast_cli_unregister_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry));
 	ast_config_engine_deregister(&pgsql_engine);
-	ast_verb(1, "Postgresql RealTime unloaded.\n");
+	ast_verb(1, "PostgreSQL RealTime unloaded.\n");
 
 	/* Unlock so something else can destroy the lock. */
 	ast_mutex_unlock(&pgsql_lock);
@@ -782,7 +776,7 @@ static int parse_config(int reload)
 
 	if (!(s = ast_variable_retrieve(config, "general", "dbuser"))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: No database user found, using 'asterisk' as default.\n");
+				"PostgreSQL RealTime: No database user found, using 'asterisk' as default.\n");
 		strcpy(dbuser, "asterisk");
 	} else {
 		ast_copy_string(dbuser, s, sizeof(dbuser));
@@ -790,7 +784,7 @@ static int parse_config(int reload)
 
 	if (!(s = ast_variable_retrieve(config, "general", "dbpass"))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: No database password found, using 'asterisk' as default.\n");
+				"PostgreSQL RealTime: No database password found, using 'asterisk' as default.\n");
 		strcpy(dbpass, "asterisk");
 	} else {
 		ast_copy_string(dbpass, s, sizeof(dbpass));
@@ -798,7 +792,7 @@ static int parse_config(int reload)
 
 	if (!(s = ast_variable_retrieve(config, "general", "dbhost"))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: No database host found, using localhost via socket.\n");
+				"PostgreSQL RealTime: No database host found, using localhost via socket.\n");
 		dbhost[0] = '\0';
 	} else {
 		ast_copy_string(dbhost, s, sizeof(dbhost));
@@ -806,7 +800,7 @@ static int parse_config(int reload)
 
 	if (!(s = ast_variable_retrieve(config, "general", "dbname"))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: No database name found, using 'asterisk' as default.\n");
+				"PostgreSQL RealTime: No database name found, using 'asterisk' as default.\n");
 		strcpy(dbname, "asterisk");
 	} else {
 		ast_copy_string(dbname, s, sizeof(dbname));
@@ -814,7 +808,7 @@ static int parse_config(int reload)
 
 	if (!(s = ast_variable_retrieve(config, "general", "dbport"))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: No database port found, using 5432 as default.\n");
+				"PostgreSQL RealTime: No database port found, using 5432 as default.\n");
 		dbport = 5432;
 	} else {
 		dbport = atoi(s);
@@ -822,7 +816,7 @@ static int parse_config(int reload)
 
 	if (!ast_strlen_zero(dbhost) && !(s = ast_variable_retrieve(config, "general", "dbsock"))) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: No database socket found, using '/tmp/pgsql.sock' as default.\n");
+				"PostgreSQL RealTime: No database socket found, using '/tmp/pgsql.sock' as default.\n");
 		strcpy(dbsock, "/tmp/pgsql.sock");
 	} else {
 		ast_copy_string(dbsock, s, sizeof(dbsock));
@@ -831,23 +825,23 @@ static int parse_config(int reload)
 
 	if (option_debug) {
 		if (!ast_strlen_zero(dbhost)) {
-			ast_debug(1, "Postgresql RealTime Host: %s\n", dbhost);
-			ast_debug(1, "Postgresql RealTime Port: %i\n", dbport);
+			ast_debug(1, "PostgreSQL RealTime Host: %s\n", dbhost);
+			ast_debug(1, "PostgreSQL RealTime Port: %i\n", dbport);
 		} else {
-			ast_debug(1, "Postgresql RealTime Socket: %s\n", dbsock);
+			ast_debug(1, "PostgreSQL RealTime Socket: %s\n", dbsock);
 		}
-		ast_debug(1, "Postgresql RealTime User: %s\n", dbuser);
-		ast_debug(1, "Postgresql RealTime Password: %s\n", dbpass);
-		ast_debug(1, "Postgresql RealTime DBName: %s\n", dbname);
+		ast_debug(1, "PostgreSQL RealTime User: %s\n", dbuser);
+		ast_debug(1, "PostgreSQL RealTime Password: %s\n", dbpass);
+		ast_debug(1, "PostgreSQL RealTime DBName: %s\n", dbname);
 	}
 
 	if (!pgsql_reconnect(NULL)) {
 		ast_log(LOG_WARNING,
-				"Postgresql RealTime: Couldn't establish connection. Check debug.\n");
-		ast_debug(1, "Postgresql RealTime: Cannot Connect: %s\n", PQerrorMessage(pgsqlConn));
+				"PostgreSQL RealTime: Couldn't establish connection. Check debug.\n");
+		ast_debug(1, "PostgreSQL RealTime: Cannot Connect: %s\n", PQerrorMessage(pgsqlConn));
 	}
 
-	ast_verb(2, "Postgresql RealTime reloaded.\n");
+	ast_verb(2, "PostgreSQL RealTime reloaded.\n");
 
 	/* Done reloading. Release lock so others can now use driver. */
 	ast_mutex_unlock(&pgsql_lock);
@@ -887,61 +881,72 @@ static int pgsql_reconnect(const char *database)
 		connInfo = NULL;
 		ast_debug(1, "pgsqlConn=%p\n", pgsqlConn);
 		if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) {
-			ast_debug(1, "Postgresql RealTime: Successfully connected to database.\n");
+			ast_debug(1, "PostgreSQL RealTime: Successfully connected to database.\n");
 			connect_time = time(NULL);
 			return 1;
 		} else {
 			ast_log(LOG_ERROR,
-					"Postgresql RealTime: Failed to connect database server %s on %s. Check debug for more info.\n",
+					"PostgreSQL RealTime: Failed to connect database server %s on %s. Check debug for more info.\n",
 					dbname, dbhost);
-			ast_debug(1, "Postgresql RealTime: Cannot Connect: %s\n", PQresultErrorMessage(NULL));
+			ast_debug(1, "PostgreSQL RealTime: Cannot Connect: %s\n", PQresultErrorMessage(NULL));
 			return 0;
 		}
 	} else {
-		ast_debug(1, "Postgresql RealTime: Everything is fine.\n");
+		ast_debug(1, "PostgreSQL RealTime: Everything is fine.\n");
 		return 1;
 	}
 }
 
-static int realtime_pgsql_status(int fd, int argc, char **argv)
+static char *handle_cli_realtime_pgsql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char status[256], status2[100] = "";
 	int ctime = time(NULL) - connect_time;
 
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "realtime pgsql status";
+		e->usage =
+			"Usage: realtime pgsql status\n"
+			"       Shows connection information for the PostgreSQL RealTime driver\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+
 	if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) {
-		if (!ast_strlen_zero(dbhost)) {
+		if (!ast_strlen_zero(dbhost))
 			snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport);
-		} else if (!ast_strlen_zero(dbsock)) {
+		else if (!ast_strlen_zero(dbsock))
 			snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock);
-		} else {
+		else
 			snprintf(status, 255, "Connected to %s@%s", dbname, dbhost);
-		}
 
-		if (!ast_strlen_zero(dbuser)) {
+		if (!ast_strlen_zero(dbuser))
 			snprintf(status2, 99, " with username %s", dbuser);
-		}
 
-		if (ctime > 31536000) {
-			ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n",
+		if (ctime > 31536000)
+			ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n",
 					status, status2, ctime / 31536000, (ctime % 31536000) / 86400,
 					(ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60);
-		} else if (ctime > 86400) {
-			ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status,
+		else if (ctime > 86400)
+			ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status,
 					status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60,
 					ctime % 60);
-		} else if (ctime > 3600) {
-			ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2,
+		else if (ctime > 3600)
+			ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2,
 					ctime / 3600, (ctime % 3600) / 60, ctime % 60);
-		} else if (ctime > 60) {
-			ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60,
+		else if (ctime > 60)
+			ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60,
 					ctime % 60);
-		} else {
-			ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime);
-		}
+		else
+			ast_cli(a->fd, "%s%s for %d seconds.\n", status, status2, ctime);
 
-		return RESULT_SUCCESS;
+		return CLI_SUCCESS;
 	} else {
-		return RESULT_FAILURE;
+		return CLI_FAILURE;
 	}
 }
 
diff --git a/res/res_config_sqlite.c b/res/res_config_sqlite.c
index 7736815941e26606811feef952dba08c6ef77852..40545a575711f90077a6993b4c473c571ea3c6d7 100644
--- a/res/res_config_sqlite.c
+++ b/res/res_config_sqlite.c
@@ -106,10 +106,6 @@
 #define RES_CONFIG_SQLITE_DRIVER "sqlite"
 #define RES_CONFIG_SQLITE_DESCRIPTION "Resource Module for SQLite 2"
 #define RES_CONFIG_SQLITE_CONF_FILE "res_config_sqlite.conf"
-#define RES_CONFIG_SQLITE_STATUS_SUMMARY "Show status information about the SQLite 2 driver"
-#define RES_CONFIG_SQLITE_STATUS_USAGE			\
-	"Usage: show sqlite status\n"			\
-	"	" RES_CONFIG_SQLITE_STATUS_SUMMARY "\n"
 
 enum {
 	RES_CONFIG_SQLITE_CONFIG_ID,
@@ -456,7 +452,7 @@ static int realtime_destroy_handler(const char *database, const char *table,
  * \param argv arguments list
  * \return RESULT_SUCCESS
  */
-static int cli_status(int fd, int argc, char *argv[]);
+static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 /*! The SQLite database object. */
 static sqlite *db;
@@ -503,12 +499,8 @@ AST_MUTEX_DEFINE_STATIC(mutex);
  * Structure containing details and callback functions for the CLI status
  * command.
  */
-static struct ast_cli_entry cli_status_cmd =
-{
-	.cmda = {"show", "sqlite", "status", NULL},
-	.handler = cli_status,
-	.summary = RES_CONFIG_SQLITE_STATUS_SUMMARY,
-	.usage = RES_CONFIG_SQLITE_STATUS_USAGE
+static struct ast_cli_entry cli_status[] = {
+	NEW_CLI(handle_cli_show_sqlite_status, "Show status information about the SQLite 2 driver"),
 };
 
 /*
@@ -1382,31 +1374,44 @@ static int realtime_destroy_handler(const char *database, const char *table,
 	return rows_num;
 }
 
-
-static int cli_status(int fd, int argc, char *argv[])
+static char *handle_cli_show_sqlite_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	ast_cli(fd, "SQLite database path: %s\n", dbfile);
-	ast_cli(fd, "config_table: ");
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "show sqlite status";
+		e->usage =
+			"Usage: show sqlite status\n"
+			"       Show status information about the SQLite 2 driver\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3)
+		return CLI_SHOWUSAGE;
+
+	ast_cli(a->fd, "SQLite database path: %s\n", dbfile);
+	ast_cli(a->fd, "config_table: ");
 
 	if (!config_table)
-		ast_cli(fd, "unspecified, must be present in extconfig.conf\n");
+		ast_cli(a->fd, "unspecified, must be present in extconfig.conf\n");
 	else
-		ast_cli(fd, "%s\n", config_table);
+		ast_cli(a->fd, "%s\n", config_table);
 
-	ast_cli(fd, "cdr_table: ");
+	ast_cli(a->fd, "cdr_table: ");
 
 	if (!cdr_table)
-		ast_cli(fd, "unspecified, CDR support disabled\n");
+		ast_cli(a->fd, "unspecified, CDR support disabled\n");
 	else
-		ast_cli(fd, "%s\n", cdr_table);
+		ast_cli(a->fd, "%s\n", cdr_table);
 
-	return RESULT_SUCCESS;
+	return CLI_SUCCESS;
 }
 
 static int unload_module(void)
 {
 	if (cli_status_registered)
-		ast_cli_unregister(&cli_status_cmd);
+		ast_cli_unregister_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
 
 	if (cdr_registered)
 		ast_cdr_unregister(RES_CONFIG_SQLITE_NAME);
@@ -1516,7 +1521,7 @@ static int load_module(void)
 		cdr_registered = 1;
 	}
 
-	error = ast_cli_register(&cli_status_cmd);
+	error = ast_cli_register_multiple(cli_status, sizeof(cli_status) / sizeof(struct ast_cli_entry));
 
 	if (error) {
 		unload_module();
diff --git a/res/res_indications.c b/res/res_indications.c
index e12b6f9a1a7c0165575ae8d59420aec7d7b4a00c..e573e4a90828588934c78a1c73feab9786b75400 100644
--- a/res/res_indications.c
+++ b/res/res_indications.c
@@ -52,22 +52,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 /* Globals */
 static const char config[] = "indications.conf";
 
-/*
- * Help for commands provided by this module ...
- */
-static char help_add_indication[] =
-"Usage: indication add <country> <indication> \"<tonelist>\"\n"
-"       Add the given indication to the country.\n";
-
-static char help_remove_indication[] =
-"Usage: indication remove <country> <indication>\n"
-"       Remove the given indication from the country.\n";
-
-static char help_show_indications[] =
-"Usage: indication show [<country> ...]\n"
-"       Display either a condensed for of all country/indications, or the\n"
-"       indications for the specified countries.\n";
-
 char *playtones_desc=
 "PlayTones(arg): Plays a tone list. Execution will continue with the next step immediately,\n"
 "while the tones continue to play.\n"
@@ -82,122 +66,159 @@ char *playtones_desc=
 
 /*!
  * \brief Add a country to indication
- * \param fd file descriptor of CLI
- * \param argc no of args
- * \param argv arguements
+ * \param e the ast_cli_entry for this CLI command
+ * \param cmd the reason we are being called
+ * \param a the arguments being passed to us
  */
-static int handle_add_indication(int fd, int argc, char *argv[])
+static char *handle_cli_indication_add(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ind_tone_zone *tz;
 	int created_country = 0;
-	if (argc != 5) return RESULT_SHOWUSAGE;
 
-	tz = ast_get_indication_zone(argv[2]);
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "indication add";
+		e->usage =
+			"Usage: indication add <country> <indication> \"<tonelist>\"\n"
+			"       Add the given indication to the country.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 5)
+		return CLI_SHOWUSAGE;
+
+	tz = ast_get_indication_zone(a->argv[2]);
 	if (!tz) {
 		/* country does not exist, create it */
-		ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n",argv[2]);
+		ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]);
 		
 		if (!(tz = ast_calloc(1, sizeof(*tz)))) {
-			return -1;
+			return CLI_FAILURE;
 		}
-		ast_copy_string(tz->country,argv[2],sizeof(tz->country));
+		ast_copy_string(tz->country, a->argv[2], sizeof(tz->country));
 		if (ast_register_indication_country(tz)) {
 			ast_log(LOG_WARNING, "Unable to register new country\n");
 			ast_free(tz);
-			return -1;
+			return CLI_FAILURE;
 		}
 		created_country = 1;
 	}
-	if (ast_register_indication(tz,argv[3],argv[4])) {
-		ast_log(LOG_WARNING, "Unable to register indication %s/%s\n",argv[2],argv[3]);
+	if (ast_register_indication(tz, a->argv[3], a->argv[4])) {
+		ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]);
 		if (created_country)
-			ast_unregister_indication_country(argv[2]);
-		return -1;
+			ast_unregister_indication_country(a->argv[2]);
+		return CLI_FAILURE;
 	}
-	return 0;
+	return CLI_SUCCESS;
 }
 
 /*!
  * \brief Remove a country from indication
- * \param fd file descriptor of CLI
- * \param argc no of args
- * \param argv arguements
+ * \param e the ast_cli_entry for this CLI command
+ * \param cmd the reason we are being called
+ * \param a the arguments being passed to us
  */
-static int handle_remove_indication(int fd, int argc, char *argv[])
+static char *handle_cli_indication_remove(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ind_tone_zone *tz;
-	if (argc != 3 && argc != 4) return RESULT_SHOWUSAGE;
 
-	if (argc == 3) {
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "indication remove";
+		e->usage =
+			"Usage: indication remove <country> <indication>\n"
+			"       Remove the given indication from the country.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 3 && a->argc != 4)
+		return CLI_SHOWUSAGE;
+
+	if (a->argc == 3) {
 		/* remove entiry country */
-		if (ast_unregister_indication_country(argv[2])) {
-			ast_log(LOG_WARNING, "Unable to unregister indication country %s\n",argv[2]);
-			return -1;
+		if (ast_unregister_indication_country(a->argv[2])) {
+			ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]);
+			return CLI_FAILURE;
 		}
-		return 0;
+		return CLI_SUCCESS;
 	}
 
-	tz = ast_get_indication_zone(argv[2]);
+	tz = ast_get_indication_zone(a->argv[2]);
 	if (!tz) {
-		ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n",argv[2],argv[3]);
-		return -1;
+		ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]);
+		return CLI_FAILURE;
 	}
-	if (ast_unregister_indication(tz,argv[3])) {
-		ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n",argv[2],argv[3]);
-		return -1;
+	if (ast_unregister_indication(tz, a->argv[3])) {
+		ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]);
+		return CLI_FAILURE;
 	}
-	return 0;
+	return CLI_SUCCESS;
 }
 
 /*!
  * \brief Show the current indications
- * \param fd file descriptor of CLI
- * \param argc no of args
- * \param argv arguements
+ * \param e the ast_cli_entry for this CLI command
+ * \param cmd the reason we are being called
+ * \param a the arguments being passed to us
  */
-static int handle_show_indications(int fd, int argc, char *argv[])
+static char *handle_cli_indication_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ind_tone_zone *tz = NULL;
 	char buf[256];
 	int found_country = 0;
 
-	if (argc == 2) {
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "indication show";
+		e->usage =
+			"Usage: indication show [<country> ...]\n"
+			"       Display either a condensed for of all country/indications, or the\n"
+			"       indications for the specified countries.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc == 2) {
 		/* no arguments, show a list of countries */
-		ast_cli(fd,"Country Alias   Description\n"
-			   "===========================\n");
-		while ( (tz = ast_walk_indications(tz) ) )
-			ast_cli(fd,"%-7.7s %-7.7s %s\n", tz->country, tz->alias, tz->description);
-		return 0;
+		ast_cli(a->fd, "Country Alias   Description\n");
+		ast_cli(a->fd, "===========================\n");
+		while ((tz = ast_walk_indications(tz)))
+			ast_cli(a->fd, "%-7.7s %-7.7s %s\n", tz->country, tz->alias, tz->description);
+		return CLI_SUCCESS;
 	}
 	/* there was a request for specific country(ies), lets humor them */
-	while ( (tz = ast_walk_indications(tz) ) ) {
-		int i,j;
-		for (i=2; i<argc; i++) {
-			if (strcasecmp(tz->country,argv[i])==0 &&
-			    !tz->alias[0]) {
+	while ((tz = ast_walk_indications(tz))) {
+		int i, j;
+		for (i = 2; i < a->argc; i++) {
+			if (strcasecmp(tz->country, a->argv[i]) == 0 && !tz->alias[0]) {
 				struct ind_tone_zone_sound* ts;
 				if (!found_country) {
 					found_country = 1;
-					ast_cli(fd,"Country Indication      PlayList\n"
-						   "=====================================\n");
+					ast_cli(a->fd, "Country Indication      PlayList\n");
+					ast_cli(a->fd, "=====================================\n");
 				}
-				j = snprintf(buf,sizeof(buf),"%-7.7s %-15.15s ",tz->country,"<ringcadence>");
-				for (i=0; i<tz->nrringcadence; i++) {
-					j += snprintf(buf+j,sizeof(buf)-j,"%d,",tz->ringcadence[i]);
+				j = snprintf(buf, sizeof(buf), "%-7.7s %-15.15s ", tz->country, "<ringcadence>");
+				for (i = 0; i < tz->nrringcadence; i++) {
+					j += snprintf(buf + j, sizeof(buf) - j, "%d,", tz->ringcadence[i]);
 				}
 				if (tz->nrringcadence)
 					j--;
-				ast_copy_string(buf+j,"\n",sizeof(buf)-j);
-				ast_cli(fd,buf);
-				for (ts=tz->tones; ts; ts=ts->next)
-					ast_cli(fd,"%-7.7s %-15.15s %s\n",tz->country,ts->name,ts->data);
+				ast_copy_string(buf + j, "\n", sizeof(buf) - j);
+				ast_cli(a->fd, buf);
+				for (ts = tz->tones; ts; ts = ts->next)
+					ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data);
 				break;
 			}
 		}
 	}
 	if (!found_country)
-		ast_cli(fd,"No countries matched your criteria.\n");
-	return -1;
+		ast_cli(a->fd, "No countries matched your criteria.\n");
+	return CLI_SUCCESS;
 }
 
 /*!
@@ -361,17 +382,9 @@ out:			v = v->next;
 
 /*! \brief CLI entries for commands provided by this module */
 static struct ast_cli_entry cli_indications[] = {
-	{ { "indication", "add", NULL },
-	handle_add_indication, "Add the given indication to the country",
-	help_add_indication, NULL },
-
-	{ { "indication", "remove", NULL },
-	handle_remove_indication, "Remove the given indication from the country",
-	help_remove_indication, NULL },
-
-	{ { "indication", "show", NULL },
-	handle_show_indications, "Display a list of all countries/indications",
-	help_show_indications },
+	NEW_CLI(handle_cli_indication_add,    "Add the given indication to the country"),
+	NEW_CLI(handle_cli_indication_remove, "Remove the given indication from the country"),
+	NEW_CLI(handle_cli_indication_show,   "Display a list of all countries/indications")
 };
 
 /*! \brief Unload indicators module */