summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2012-07-26 15:31:05 +0000
committerJonathan Rose <jrose@digium.com>2012-07-26 15:31:05 +0000
commit3da07b3ec00daa9f8d93328e5e7ddf6dcb960c0b (patch)
tree399cd3bd9e10bdd15d3381e4098cb67e07e8dbed /channels/chan_sip.c
parent79de3f7fe8c0f71a57f65028ddc9fee5ab0b76bc (diff)
chan_sip: Add SIPpeerstatus command to AMI
This patch was submitted by mnicholson a while back. It adds a new AMI action which allows users to request SIP peer status on demand similar to existing PeerStatus events and to the output you would see from CLI with sip show peer Review: https://reviewboard.asterisk.org/r/1098/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370518 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 3c645c481..951bb1584 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -572,6 +572,21 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
via multiple <literal>Variable: name=value</literal> sequences.</para>
</description>
</manager>
+ <manager name="SIPpeerstatus" language="en_US">
+ <synopsis>
+ Show the status of one or all of the sip peers.
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Peer" required="false">
+ <para>The peer name you want to check.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Retrieves the status of one or all of the sip peers. If no peer name is specified, status
+ for all of the sip peers will be retrieved.</para>
+ </description>
+ </manager>
<info name="SIPMessageFromInfo" language="en_US" tech="SIP">
<para>The <literal>from</literal> parameter can be a configured peer name
or in the form of "display-name" &lt;URI&gt;.</para>
@@ -18789,6 +18804,92 @@ static char *sip_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args
return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
}
+static void send_manager_peer_status(struct mansession *s, struct sip_peer *peer, const char *idText)
+{
+ char time[128] = "";
+ char status[128] = "";
+ if (peer->maxms) {
+ if (peer->lastms < 0) {
+ snprintf(status, sizeof(status), "PeerStatus: Unreachable\r\n");
+ } else if (peer->lastms > peer->maxms) {
+ snprintf(status, sizeof(status), "PeerStatus: Lagged\r\n");
+ snprintf(time, sizeof(time), "Time: %d\r\n", peer->lastms);
+ } else if (peer->lastms) {
+ snprintf(status, sizeof(status), "PeerStatus: Reachable\r\n");
+ snprintf(time, sizeof(time), "Time: %d\r\n", peer->lastms);
+ } else {
+ snprintf(status, sizeof(status), "PeerStatus: Unknown\r\n");
+ }
+ } else {
+ snprintf(status, sizeof(status), "PeerStatus: Unmonitored\r\n");
+ }
+
+ astman_append(s,
+ "Event: PeerStatus\r\n"
+ "Privilege: System\r\n"
+ "ChannelType: SIP\r\n"
+ "Peer: SIP/%s\r\n"
+ "%s"
+ "%s"
+ "%s"
+ "\r\n",
+ peer->name, status, time, idText);
+}
+
+/*! \brief Show SIP peers in the manager API */
+static int manager_sip_peer_status(struct mansession *s, const struct message *m)
+{
+ const char *id = astman_get_header(m,"ActionID");
+ const char *peer_name = astman_get_header(m,"Peer");
+ char idText[256] = "";
+ struct sip_peer *peer = NULL;
+
+ if (!ast_strlen_zero(id)) {
+ snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
+ }
+
+ if (!ast_strlen_zero(peer_name)) {
+ /* strip SIP/ from the begining of the peer name */
+ if (strlen(peer_name) >= 4 && !strncasecmp("SIP/", peer_name, 4)) {
+ peer_name += 4;
+ }
+
+ peer = sip_find_peer(peer_name, NULL, TRUE, FINDPEERS, FALSE, 0);
+ if (!peer) {
+ astman_send_error(s, m, "No such peer");
+ return 0;
+ }
+ }
+
+ astman_send_ack(s, m, "Peer status will follow");
+
+ if (!peer) {
+ struct ao2_iterator i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table for SIPpeerstatus"))) {
+ ao2_lock(peer);
+ send_manager_peer_status(s, peer, idText);
+ ao2_unlock(peer);
+ sip_unref_peer(peer, "unref peer for SIPpeerstatus");
+ }
+ ao2_iterator_destroy(&i);
+ } else {
+ ao2_lock(peer);
+ send_manager_peer_status(s, peer, idText);
+ ao2_unlock(peer);
+ sip_unref_peer(peer, "unref peer for SIPpeerstatus");
+ }
+
+
+ astman_append(s,
+ "Event: SIPpeerstatusComplete\r\n"
+ "%s"
+ "\r\n",
+ idText);
+
+ return 0;
+}
+
+
/*! \brief Send qualify message to peer from cli or manager. Mostly for debugging. */
static char *_sip_qualify_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
{
@@ -32789,6 +32890,7 @@ static int load_module(void)
ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer);
ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry);
ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify);
+ ast_manager_register_xml("SIPpeerstatus", EVENT_FLAG_SYSTEM, manager_sip_peer_status);
sip_poke_all_peers();
sip_keepalive_all_peers();
sip_send_all_registers();
@@ -32898,6 +33000,7 @@ static int unload_module(void)
ast_manager_unregister("SIPqualifypeer");
ast_manager_unregister("SIPshowregistry");
ast_manager_unregister("SIPnotify");
+ ast_manager_unregister("SIPpeerstatus");
/* Kill TCP/TLS server threads */
if (sip_tcp_desc.master) {