📄 agent.c
字号:
/* * Copyright (C) 2006 Voop as * Thorsten Lockert <tholo@voop.as> * * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. *//*! \file * * \brief SNMP Agent / SubAgent support for Asterisk * * \author Thorsten Lockert <tholo@voop.as> */#include "asterisk.h"ASTERISK_FILE_VERSION(__FILE__, "$Revision: 33482 $")#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "asterisk/channel.h"#include "asterisk/logger.h"#include "asterisk/options.h"#include "asterisk/indications.h"#include "asterisk/version.h"#include "asterisk/pbx.h"/* Colission between Net-SNMP and Asterisk */#define unload_module ast_unload_module#include "asterisk/module.h"#undef unload_module#include "agent.h"/* Helper functions in Net-SNMP, header file not installed by default */int header_generic(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **);int header_simple_table(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **, int);int register_sysORTable(oid *, size_t, const char *);int unregister_sysORTable(oid *, size_t);/* Not defined in header files */extern char ast_config_AST_SOCKET[];/* Forward declaration */static void init_asterisk_mib(void);/* * Anchor for all the Asterisk MIB values */static oid asterisk_oid[] = { 1, 3, 6, 1, 4, 1, 22736, 1 };/* * MIB values -- these correspond to values in the Asterisk MIB, * and MUST be kept in sync with the MIB for things to work as * expected. */#define ASTVERSION 1#define ASTVERSTRING 1#define ASTVERTAG 2#define ASTCONFIGURATION 2#define ASTCONFUPTIME 1#define ASTCONFRELOADTIME 2#define ASTCONFPID 3#define ASTCONFSOCKET 4#define ASTMODULES 3#define ASTMODCOUNT 1#define ASTINDICATIONS 4#define ASTINDCOUNT 1#define ASTINDCURRENT 2#define ASTINDTABLE 3#define ASTINDINDEX 1#define ASTINDCOUNTRY 2#define ASTINDALIAS 3#define ASTINDDESCRIPTION 4#define ASTCHANNELS 5#define ASTCHANCOUNT 1#define ASTCHANTABLE 2#define ASTCHANINDEX 1#define ASTCHANNAME 2#define ASTCHANLANGUAGE 3#define ASTCHANTYPE 4#define ASTCHANMUSICCLASS 5#define ASTCHANBRIDGE 6#define ASTCHANMASQ 7#define ASTCHANMASQR 8#define ASTCHANWHENHANGUP 9#define ASTCHANAPP 10#define ASTCHANDATA 11#define ASTCHANCONTEXT 12#define ASTCHANMACROCONTEXT 13#define ASTCHANMACROEXTEN 14#define ASTCHANMACROPRI 15#define ASTCHANEXTEN 16#define ASTCHANPRI 17#define ASTCHANACCOUNTCODE 18#define ASTCHANFORWARDTO 19#define ASTCHANUNIQUEID 20#define ASTCHANCALLGROUP 21#define ASTCHANPICKUPGROUP 22#define ASTCHANSTATE 23#define ASTCHANMUTED 24#define ASTCHANRINGS 25#define ASTCHANCIDDNID 26#define ASTCHANCIDNUM 27#define ASTCHANCIDNAME 28#define ASTCHANCIDANI 29#define ASTCHANCIDRDNIS 30#define ASTCHANCIDPRES 31#define ASTCHANCIDANI2 32#define ASTCHANCIDTON 33#define ASTCHANCIDTNS 34#define ASTCHANAMAFLAGS 35#define ASTCHANADSI 36#define ASTCHANTONEZONE 37#define ASTCHANHANGUPCAUSE 38#define ASTCHANVARIABLES 39#define ASTCHANFLAGS 40#define ASTCHANTRANSFERCAP 41#define ASTCHANTYPECOUNT 3#define ASTCHANTYPETABLE 4#define ASTCHANTYPEINDEX 1#define ASTCHANTYPENAME 2#define ASTCHANTYPEDESC 3#define ASTCHANTYPEDEVSTATE 4#define ASTCHANTYPEINDICATIONS 5#define ASTCHANTYPETRANSFER 6#define ASTCHANTYPECHANNELS 7void *agent_thread(void *arg){ ast_verbose(VERBOSE_PREFIX_2 "Starting %sAgent\n", res_snmp_agentx_subagent ? "Sub" : ""); snmp_enable_stderrlog(); if (res_snmp_agentx_subagent) netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); init_agent("asterisk"); init_asterisk_mib(); init_snmp("asterisk"); if (!res_snmp_agentx_subagent) init_master_agent(); while (res_snmp_dont_stop) agent_check_and_process(1); snmp_shutdown("asterisk"); ast_verbose(VERBOSE_PREFIX_2 "Terminating %sAgent\n", res_snmp_agentx_subagent ? "Sub" : ""); return NULL;}static u_char *ast_var_channels(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ static unsigned long long_ret; if (header_generic(vp, name, length, exact, var_len, write_method)) return NULL; switch (vp->magic) { case ASTCHANCOUNT: long_ret = ast_active_channels(); return (u_char *)&long_ret; default: break; } return NULL;}static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ static unsigned long long_ret; static u_char bits_ret[2]; static char string_ret[256]; struct ast_channel *chan, *bridge; struct timeval tval; u_char *ret; int i, bit; if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels())) return NULL; i = name[*length - 1] - 1; for (chan = ast_channel_walk_locked(NULL); chan && i; chan = ast_channel_walk_locked(chan), i--) ast_channel_unlock(chan); if (chan == NULL) return NULL; *var_len = sizeof(long_ret); switch (vp->magic) { case ASTCHANINDEX: long_ret = name[*length - 1]; ret = (u_char *)&long_ret; break; case ASTCHANNAME: if (!ast_strlen_zero(chan->name)) { strncpy(string_ret, chan->name, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANLANGUAGE: if (!ast_strlen_zero(chan->language)) { strncpy(string_ret, chan->language, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANTYPE: strncpy(string_ret, chan->tech->type, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMUSICCLASS: if (!ast_strlen_zero(chan->musicclass)) { strncpy(string_ret, chan->musicclass, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANBRIDGE: if ((bridge = ast_bridged_channel(chan)) != NULL) { strncpy(string_ret, bridge->name, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANMASQ: if (chan->masq && !ast_strlen_zero(chan->masq->name)) { strncpy(string_ret, chan->masq->name, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANMASQR: if (chan->masqr && !ast_strlen_zero(chan->masqr->name)) { strncpy(string_ret, chan->masqr->name, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANWHENHANGUP: if (chan->whentohangup) { gettimeofday(&tval, NULL); long_ret = difftime(chan->whentohangup, tval.tv_sec) * 100 - tval.tv_usec / 10000; ret= (u_char *)&long_ret; } else ret = NULL; break; case ASTCHANAPP: if (chan->appl) { strncpy(string_ret, chan->appl, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANDATA: if (chan->data) { strncpy(string_ret, chan->data, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANCONTEXT: strncpy(string_ret, chan->context, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMACROCONTEXT: strncpy(string_ret, chan->macrocontext, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMACROEXTEN: strncpy(string_ret, chan->macroexten, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMACROPRI: long_ret = chan->macropriority; ret = (u_char *)&long_ret; break; case ASTCHANEXTEN: strncpy(string_ret, chan->exten, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANPRI: long_ret = chan->priority; ret = (u_char *)&long_ret; break; case ASTCHANACCOUNTCODE: if (!ast_strlen_zero(chan->accountcode)) { strncpy(string_ret, chan->accountcode, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANFORWARDTO: if (!ast_strlen_zero(chan->call_forward)) { strncpy(string_ret, chan->call_forward, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANUNIQUEID: strncpy(string_ret, chan->uniqueid, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANCALLGROUP: long_ret = chan->callgroup; ret = (u_char *)&long_ret; break; case ASTCHANPICKUPGROUP: long_ret = chan->pickupgroup; ret = (u_char *)&long_ret; break; case ASTCHANSTATE: long_ret = chan->_state & 0xffff; ret = (u_char *)&long_ret; break; case ASTCHANMUTED: long_ret = chan->_state & AST_STATE_MUTE ? 1 : 2; ret = (u_char *)&long_ret; break; case ASTCHANRINGS: long_ret = chan->rings; ret = (u_char *)&long_ret; break; case ASTCHANCIDDNID: if (chan->cid.cid_dnid) { strncpy(string_ret, chan->cid.cid_dnid, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANCIDNUM: if (chan->cid.cid_num) { strncpy(string_ret, chan->cid.cid_num, sizeof(string_ret)); string_ret[sizeof(string_ret) - 1] = '\0'; *var_len = strlen(string_ret); ret = (u_char *)string_ret; } else ret = NULL; break; case ASTCHANCIDNAME:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -