/*
 * SNMPStats Module
 * Copyright (C) 2006 SOMA Networks, INC.
 * Written by: Jeffrey Magder (jmagder@somanetworks.com)
 *
 * This file is part of opensips, a free SIP server.
 *
 * opensips is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version
 *
 * opensips is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 *
 * History:
 * --------
 * 2006-11-23 initial version (jmagder)
 * 2007-02-16 Moved all OID registrations from the experimental branch to
 *            OpenSER's IANA assigned enterprise branch. (jmagder)
 *
 * Note: this file originally auto-generated by mib2c using
 * mib2c.array-user.conf
 *
 * This file defines the prototypes that implement the openserSIPRegUserTable.
 * For a full description of the table, please see the OPENSER-SIP-SERVER-MIB.
 *
 * Understanding this code will be much simpler with the following information:
 *
 * 1) All rows are indexed by an integer user index.  This is different from the
 *    usrloc module, which indexes by strings.  This less natural indexing
 *    scheme was required due to SNMP String index limitations.  (for example,
 *    SNMP has maximum index lengths.)
 *
 * 2) We need a quick way of mapping usrloc indices to our integer indices.  For
 *    this reason a string indexed Hash Table was created, with each entry mapping
 *    to an integer user index.
 *
 *    This hash table is used by the openserSIPContactTable (the hash table also
 *    maps a user to its contacts), as well as the openserSIPRegUserLookupTable.
 *    The hash table is also used for quick lookups when a user expires. (i.e, it
 *    gives us a more direct reference, instead of having to search the whole
 *    table).
 *
 * 3) We are informed about new/expired users via a callback mechanism from the
 *    usrloc module.  Because of NetSNMP inefficiencies, we had to abstract this
 *    process.  Specifically:
 *
 *    - It can take a long time for the NetSNMP code base to populate a table with
 *      a large number of records.
 *
 *    - We rely on callbacks for updated user information.
 *
 *    Clearly, using the SNMPStats module in this situation could lead to some
 *    big performance loses if we don't find another way to deal with this.  The
 *    solution was to use an interprocess communications buffer.
 *
 *    Instead of adding the record directly to the table, the callback functions
 *    now adds either an add/delete command to the interprocessBuffer.  When an
 *    snmp request is recieved by the SNMPStats sub-process, it will consume
 *    this interprocess buffer, adding and deleting users.  When it is finished,
 *    it can service the SNMP request.
 *
 *    This doesn't remove the NetSNMP inefficiency, but instead moves it to a
 *    non-critical path.  Such an approach allows SNMP support with almost no
 *    overhead to the rest of OpenSIPS.
 */

#ifndef OPENSERSIPREGUSERTABLE_H
#define OPENSERSIPREGUSERTABLE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/library/container.h>
#include <net-snmp/agent/table_array.h>

#include "../../config.h"

/* Defines what each SNMP Row is made of. */
typedef struct openserSIPRegUserTable_context_s
{
	netsnmp_index index;

	unsigned long openserSIPUserIndex;

	/* There are potentially a lot of these of varying sizes, so lets
	 * allocate only the amount of memory we need when the row is
	 * created. */
	unsigned char *openserSIPUserUri;

	long openserSIPUserUri_len;

	unsigned long openserSIPUserAuthenticationFailures;

	void * data;

} openserSIPRegUserTable_context;

/*******************************/
/*    Customized Prototypes    */
/*******************************/

/* If the usrloc module is loaded, this function will grab hooks into its
 * callback registration function, and add handleContactCallbacks() as the
 * callback for UL_CONTACT_INSERT and UL_CONTACT_EXPIRE.
 *
 * Returns 1 on success, and zero otherwise */
int registerForUSRLOCCallbacks();

/*
 * Creates a row and inserts it.
 *
 * Returns: The rows userIndex on success, and 0 otherwise.
 */
int  createRegUserRow(char *stringToRegister);


/* Removes an SNMP row indexed by userIndex, and frees the string and index it
 * pointed to. */
void  deleteRegUserRow(int userIndex);

/* Creates an 'aor to userindex' record from stringName and userIndex, and pushes
 * them onto the hash table. */
void  pushUserIntoHashTable(int userIndex, char *stringName);

/*
 * Adds or updates a user:
 *
 *   - If a user with the name userName exists, its 'number of contacts' count
 *     will be incremented.
 *   - If the user doesn't exist, the user will be added to the table, and its
 *     number of contacts' count set to 1.
 */
void updateUser(char *userName);

/*******************************/
/* Normal Function Prototypes  */
/*******************************/

/* Initializes the openserSIPRegUserTable module.  */
void  init_openserSIPRegUserTable(void);

/*
 * Initialize the openserSIPRegUserTable table by defining its contents and how
 * it's structured
 */
void  initialize_table_openserSIPRegUserTable(void);

const openserSIPRegUserTable_context * openserSIPRegUserTable_get_by_idx(
		netsnmp_index *);

const openserSIPRegUserTable_context * openserSIPRegUserTable_get_by_idx_rs(
		netsnmp_index *, int row_status);

/* Handles SNMP GET requests. */
int   openserSIPRegUserTable_get_value(
		netsnmp_request_info *,
		netsnmp_index *,
		netsnmp_table_request_info *);

/* OID Declarations. */
extern oid openserSIPRegUserTable_oid[];
extern size_t openserSIPRegUserTable_oid_len;

#define openserSIPRegUserTable_TABLE_OID OPENSER_OID,3,1,2,1,5,6

/* Column Definitions */
#define COLUMN_OPENSERSIPUSERINDEX                  1
#define COLUMN_OPENSERSIPUSERURI                    2
#define COLUMN_OPENSERSIPUSERAUTHENTICATIONFAILURES 3

#define openserSIPRegUserTable_COL_MIN 2
#define openserSIPRegUserTable_COL_MAX 3

#ifdef __cplusplus
}
#endif

#endif /** OPENSERSIPREGUSERTABLE_H */
