/*
** SellaNMS
** $Id: snmp.h,v 1.10 2005/05/15 05:21:17 sella Exp $
** Copyright (c) 2001-2005 Digital Genesis Software, LLC. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
*/

#ifndef __DGS_MODULE_MONITOR_SNMP_H
#define __DGS_MODULE_MONITOR_SNMP_H

#ifdef HAVE_CONFIG_H
	#include "config.h"
#endif

#include "defaults.h"
#include "util.h"
#include "netblock.h"
#include "storagedata.h"
#include "../monitor.h"
#include "rrdtool/rrdtool.h"
#include "policy_framework/policy_framework.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#ifdef HAVE_NET_SNMP
	#include <net-snmp/net-snmp-config.h>
	#include <net-snmp/net-snmp-includes.h>
	#include <net-snmp/library/default_store.h>
#else
	#include <ucd-snmp/ucd-snmp-config.h>
	#include <ucd-snmp/ucd-snmp-includes.h>
	#include <ucd-snmp/default_store.h>
	#define NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE	RECEIVED_MESSAGE
	#define NETSNMP_CALLBACK_OP_TIMED_OUT			TIMED_OUT
	#define NETSNMP_CALLBACK_OP_SEND_FAILED		SEND_FAILED
	#define NETSNMP_CALLBACK_OP_CONNECT				4
	#define NETSNMP_CALLBACK_OP_DISCONNECT			5
#endif
#include <stl/list>
#include <stl/queue>
#include <stl/list>
#include <stl/string>

#define MODULE_MONITOR_SNMP_INTERVAL_DEFAULT 600
#define MODULE_MONITOR_SNMP_QUEUEDEPTH_DEFAULT 1000
#define MODULE_MONITOR_SNMP_TTL_DEFAULT 3
#define MODULE_MONITOR_SNMP_REPETITIONS_DEFAULT 1000
#define MODULE_MONITOR_SNMP_MAXELEMENETS_DEFAULT 32

typedef struct _tx_element_t {
	class SNMP*	instance;
	time_t	start;				/* Last start time */
	snmp_session *session;		/* Current session */
	string	element;				/* Element IP */
	string	community;			/* Community for this element */
	bool		oid_done;			/* Current oid done? */
	slist<string> oids;			/* List of oids for this element */
	slist<string>::iterator oids_it; /* Iterator for oids list */
	oid		root[MAX_OID_LEN]; /* Current oid/root */
	size_t	rootlen;				/* Current oid lenght */
} tx_element_t;
typedef slist<tx_element_t> tx_slist_t;

typedef struct _snmp_data_t {
	unsigned	element;
	time_t	stamp;

	u_char	type;

	string	oid;
	string	value;
} snmp_data_t;

typedef queue<snmp_data_t>	bulk_queue_t;

typedef struct _oid_data_t {
	time_t	stamp;

	u_char	type;
	string	value;
} oid_data_t;

typedef hash_map<string, oid_data_t>	oid_map_t;

typedef struct _element_data_t {
	unsigned		element;

	oid_map_t	oids;
} element_data_t;

typedef hash_map<unsigned, element_data_t> element_map_t;
typedef queue<element_data_t> element_queue_t;

class SNMP: public Monitor {
	public:
		SNMP();
		~SNMP();

	protected:
		bulk_queue_t		bulk_queue;
		pthread_mutex_t	bulk_mutex;

		element_queue_t	element_queue;
		pthread_mutex_t	element_mutex;

	private:
		virtual RESULT execute();
		virtual RESULT readConfig();
		virtual RESULT printConfig();

		static RESULT transmit_thread(void *args);
		static RESULT policy_thread(void *args);
		static RESULT calc_thread(void *args);
		static int receive_callback(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic);

		tx_slist_t			txList;
		RRDTool				rrdtool;

		unsigned long		module_id;
		unsigned long		interval;
		uint32_t				source;
		unsigned long		repetitions;

		unsigned long		queueDepth;
		unsigned long		timeout;
		unsigned long		maxElements;
};

#endif

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim600: fdm=marker
** vim: noet ts=3 sw=3
*/
