[asterisk-commits] branch oej/aum-trunk - r7475 in /team/oej/aum-trunk: include/asterisk/ res/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Dec 14 15:07:32 CST 2005


Author: oej
Date: Wed Dec 14 15:07:27 2005
New Revision: 7475

URL: http://svn.digium.com/view/asterisk?rev=7475&view=rev
Log:
Adding the AUM source code

Added:
    team/oej/aum-trunk/include/asterisk/aum.h
    team/oej/aum-trunk/res/res_aum.c
Modified:
    team/oej/aum-trunk/res/Makefile

Added: team/oej/aum-trunk/include/asterisk/aum.h
URL: http://svn.digium.com/view/asterisk/team/oej/aum-trunk/include/asterisk/aum.h?rev=7475&view=auto
==============================================================================
--- team/oej/aum-trunk/include/asterisk/aum.h (added)
+++ team/oej/aum-trunk/include/asterisk/aum.h Wed Dec 14 15:07:27 2005
@@ -1,0 +1,475 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Asterisk User Management interface
+ *
+ * Copyright (C) 2005, Edvina AB, Sollentuna, Sweden
+ *
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * 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.
+ */
+
+/*!\note This is just skeletons, that I'm trying to put flesh and	
+	clothes on... Mail input to oej at edvina.net
+*/
+
+/*!\file
+ * \brief Asterisk User Managment - AUM - API
+ * \arg Implemented in res_aum.c
+ * \par For information on AUM, please see
+ *  	\arg AUM_desc
+ */
+
+#ifndef _ASTERISK_AUM_H
+#define _ASTERISK_AUM_H
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*--------------------------- AUM STRING HANDLING -------------------------------- */
+/*! Character set definition for some strings */
+enum aum_string_charset {
+	AUM_CHAR_UNKNOWN = 0,
+	AUM_CHAR_ASCII,			/*!< 7 bit ASCII */
+	AUM_CHAR_ISO8859_1,		/*!< ISO 8859-1, 8 bits */
+	AUM_CHAR_ISO8859_2,		/*!< ISO 8859-2, 8 bits */
+	AUM_CHAR_ISO8859_3,		/*!< ISO 8859-3, 8 bits */
+	AUM_CHAR_UTF8,			/*!< Unicode ISO 9660, UTF 8 encoding */
+};
+
+struct aum_string_convert {
+	enum aum_string_charset	charset;	/*!< Character set */
+	const char *label;			/*!< Label used in strings in config files */
+};
+
+/*! String object for international strings. 
+	\note Use the aum_string functions to assign values, get strings in alternative 
+	character sets and free the chain of strings 
+	OEJ: This is a simple linked list. Wonder if the AST_LIST is needed here?
+*/
+struct aum_string_struct {
+	char 		*string;	/*!< Allocated string, needs to be free()d after use */
+	size_t		size;		/*!< Allocated size, if allocated (Won't free unless we have size */
+	enum aum_string_charset charset;	/*!< Character set for this string */
+	struct aum_string *next;	/*!< Pointers to alternative encodings of the same string */
+};
+
+typedef struct aum_string_struct aum_string;
+
+/*! \brief Address types for address objects in AUM */
+enum aum_address_type {
+	AUM_ADDR_EMAIL 	= (1 << 0),	/*!< E-mail - string like "username at domain.se" */
+	AUM_ADDR_XMPP	= (1 << 1),	/*!< XMPP uri */
+	AUM_ADDR_SIP	= (1 << 2),	/*!< SIP uri */
+	AUM_ADDR_MSN	= (1 << 3),	/*!< MSN user identifier "username at hotmail.com" */
+	AUM_ADDR_AOL	= (1 << 4),	/*!< AOL/ICQ user ID */
+	AUM_ADDR_TEL	= (1 << 5),	/*!< E.164 phone number (TEL-uri format, local allowed (depends on your configuration) */
+	AUM_ADDR_CELL_TEL = (1 << 6),	/*!< Cell phone E.164 phone number (TEL-uri format, local allowed (depends on your configuration) */
+	AUM_ADDR_IAX2	= (1 << 7),	/*!< IAX2 callable uri, like "guest at myasterisk.com/12345"	*/
+	AUM_ADDR_FWD	= (1 << 8),	/*!< Free World Dialup User ID */
+	AUM_ADDR_IAXTEL	= (1 << 9),	/*!< IAXtel Dialup User ID */
+	AUM_ADDR_FAX	= (1 << 10),	/*!< Preferred fax number (E.164 Tel URI) */
+	AUM_ADDR_WEB	= (1 << 11),	/*!< HOMEPAGE */
+	AUM_ADDR_NONE	= (1 << 30),	/*!< Return value */
+};
+
+/*! \brief Things you can configure in AUM */
+enum aum_config_objects {
+	AUM_CONFOBJ_GENERAL	= (1 << 0),	/*!< General configuration options */
+	AUM_CONFOBJ_USER	= (1 << 1),	/*!< User configuration */ 
+	AUM_CONFOBJ_GROUP	= (1 << 2),	/*!< Group configuration */
+};
+
+/*! \brief AUM configuration options */
+enum aum_config_options {
+	AUM_CNF_NONE,			/*!< Unknown configuration directive */
+	AUM_CNF_NOT_VALID_FOR_OBJECT,	/*!< Not valid for this object */
+	AUM_CNF_NOT_FOUND,		/*!< No match found */
+	AUM_CNF_ADDR_EMAIL,		/*!< Email address */
+	AUM_CNF_ADDR_XMPP,		/*!< XMPP/Jabber address */
+	AUM_CNF_ADDR_SIP,		/*!< SIP AOR: SIP uri to reach this user */
+	AUM_CNF_ADDR_IAX2,		/*!< IAX2 URI */
+	AUM_CNF_ADDR_AOL,		/*!< AOL IM */
+	AUM_CNF_ADDR_MSN,		/*!< MSN Contat for IM */
+	AUM_CNF_ADDR_TEL,		/*!< Telephone numer in E.164 format */
+	AUM_CNF_ADDR_CELL_TEL,		/*!< Cell phone number */
+	AUM_CNF_ADDR_FAX,		/*!< Fax number (PSTN) */
+	AUM_CNF_ADDR_FWD,		/*!< Free World Dialup account */
+	AUM_CNF_ADDR_IAXTEL,		/*!< IAXtel account ID */
+	AUM_CNF_ADDR_WEB,		/*!< Home page */
+	AUM_CNF_VMAILBOX,		/*!< Voicemail mailbox exten at context */
+	AUM_CNF_GROUP,			/*!< Group membership */
+	AUM_CNF_CALLBACKEXT,		/*!< Default extension */
+	AUM_CNF_PARKING,		/*!< Default parking context */
+	AUM_CNF_DISACONTEXT,		/*!< DISA context for disa() access */
+	AUM_CNF_SIPDOMAIN,		/*!< SIP DOMAIN this user belongs to (virtual PBX) */
+	AUM_CNF_SUBSCRIBECONTEXT,	/*!< SIP subscription context */
+	AUM_CNF_DEFEXTEN,		/*!< Default extension */
+	AUM_CNF_DEFCONTEXT,		/*!< Default context */
+	AUM_CNF_CID,			/*!< Caller ID */
+	AUM_CNF_CALLERPRES,		/*!< Caller ID presentation when making calls */
+	AUM_CNF_ACCOUNTCODE,		/*!< Account code for this user */
+	AUM_CNF_MANAGERACCESS,		/*!< Manager access something */
+	AUM_CNF_SECRET,			/*!< Secret (password) */
+	AUM_CNF_PIN,			/*!< Pin code for authorization by DTMF */
+	AUM_CNF_CALLGROUP,		/*!< Calling group */
+	AUM_CNF_PICKUPGROUP,		/*!< Pickup group */
+	AUM_CNF_IAX2KEY,		/*!< Name of IAX key */
+	AUM_CNF_MUSICCLASS,		/*!< Default music class when this user puts someone on hold */
+	AUM_CNF_LDAPDN,			/*!< LDAP handle for this user */
+	AUM_CNF_FIRSTNAME,		/*!< First name */
+	AUM_CNF_LASTNAME,		/*!< Last name*/
+	AUM_CNF_TITLE,			/*!< Title */
+	AUM_CNF_LANGUAGE,		/*!< Language */
+	AUM_CNF_SOUNDNAME,		/*!< Sound file */
+	AUM_CNF_CHANVAR,		/*!< Channel variables */
+	AUM_CNF_PERMIT,			/*!< ACL permit */
+	AUM_CNF_DENY,			/*!< ACL deny */
+	AUM_CNF_NUMID,			/*!< Numerical ID for this user */
+	AUM_CNF_TIMEZONE,		/*!< Timezone, mostly used for voice mail */
+	AUM_CNF_GROUPVAR,		/*!< */
+	AUM_CNF_TYPE,			/*!< Type of config - group, user */
+	AUM_CNF_GROUPDESC,		/*!< Group description */
+	AUM_CNF_DEBUG,			/*!< AUM debug option */
+};
+
+/*! \brief AUM configuration definition structure */
+struct aum_config_struct {
+	enum aum_config_options option;
+	char 			*label;
+	enum aum_config_objects valid;
+};
+
+/*! \brief AUM Address object */
+struct aum_address {
+ 	enum aum_address_type type;		/*!< Address type */
+	enum aum_string_charset charset;		/*!< character set */
+	char address[180];			/*!< The actual address */
+	int active;
+	AST_LIST_ENTRY(aum_address) list;	/*!< List mechanics */
+};
+
+/*! \brief AUM Address configuration helper */
+struct aum_address_config_struct {
+	enum aum_address_type	type;
+	char 			*label;
+	char 			*display;
+	enum aum_config_options configoption;
+};
+
+/*! \brief Context types for AUM user objects */
+enum aum_context_type {
+	AUM_CONTEXT_NONE = 0,	/*!< No Context (Return value for functions) */
+	AUM_CONTEXT_DEF_CB,	/*!< Default callback context for reaching this user */
+	AUM_CONTEXT_DEF_INCOMING,	/*!< Default incoming context for this user */
+	AUM_CONTEXT_VOICEMAIL,	/*!< Default voicemail context */
+	AUM_CONTEXT_DISA,	/*!< Default DISA context */
+	AUM_CONTEXT_SIPSUBSCRIBE,	/*!< Default context for SIP subscriptions */
+	AUM_CONTEXT_PARKING,	/*!< Default parking context */
+};
+
+/*! \brief Explanations of contexts */
+struct aum_context_table {
+	enum aum_context_type	type;
+	const char *desc;
+};
+
+/*! \brief Presence states for AUM user objects */
+enum aum_presence_state {	/* This follows XMPP roughly */
+	AUM_PRES_NOT_AVAILABLE,	/*!< No presence available */
+	AUM_PRES_AVAILABLE,	/*!< Reachable, on line */
+	AUM_PRES_MEETING,	/*!< Meeting */
+	AUM_PRES_ONCALL,	/*!< On call */
+	AUM_PRES_DND,		/*!< Do not disturb */
+	AUM_PRES_EXT_AWAY,	/*!< Extended away */
+};
+
+/*! \brief Presence providers */
+enum aum_presence_prov {
+	AUM_PRESPROV_XMPP,	/*!< Jabber/XMPP */	
+	AUM_PRESPROV_MSN,	/*!< MSN Messenger */
+	AUM_PRESPROV_SIMPLE,	/*!< SIP Simple */
+	AUM_PRESPROV_AMI,	/*!< AMI - Asterisk manager interface */
+	AUM_PRESPROV_DIALPLAN,	/*!< Dialplan functions */
+	AUM_PRESPROV_CLI,	/*!< CLI functions */
+};
+
+/*! \brief Presence structures for AUM presence objects */
+struct aum_presence {
+	enum aum_presence_state	state;		/*!< State of this user */
+	enum aum_presence_prov provider;	/*!< Provider of presence */
+	AST_LIST_ENTRY(aum_presence) list;	/*!< List mechanics */
+};
+
+enum devicereg {
+	AUM_DEVICE_REG_CHANNEL,			/* Added by channel, persistent object */
+	AUM_DEVICE_REG_MANAGER,			/*!< Added by manager, non persistant */
+	AUM_DEVICE_REG_CLI,			/*!< Added by the CLI, non persistant */
+};
+
+/*! \brief List of phones that belongs to this user
+ * For now, kept in memory. Not persistent across reloads... Could use
+ * ASTdb... 
+ */
+struct aum_device {
+	char *devicename;			/*!< tech/devicename */
+	struct ast_flags flags;			/*!< flags class AUM_DEVICE_* */
+	/*! Placeholder for callback to channel to change state */
+	int (* const change_devstate)(char *device, enum aum_presence_state);
+	enum devicereg registrar;		/*!< Device registrar */
+	AST_LIST_ENTRY(aum_device) list;
+};
+
+/*! \brief Context structure 
+	\note Until further notice, Asterisk contexts are ASCII
+*/
+struct aum_context {
+	enum aum_context_type type;		/*!< Context type */
+	char context[AST_MAX_CONTEXT];		/*!< Context name */
+	AST_LIST_ENTRY(aum_context) list;	/*!< List mechanics */
+};
+
+
+/*! \brief Group memberships */
+struct aum_group_member {
+	int priority;				/*!< Not defined yet... */
+	union {
+		struct aum_group *group;	/*!< For users, pointer to groups */
+		struct aum_user *user;		/*!< For groups, pointer to users */
+	};
+	AST_LIST_ENTRY(aum_group_member) list;	/*!< List mechanics */
+};
+
+/*! \brief Flags for aum_user flag field */
+enum aum_user_flags {
+	AUM_USER_FLAG_REALTIME = (1 << 0),	/*!< User loaded from realtime */
+	AUM_USER_FLAG_DISABLED = (1 << 1),	/*!< User disabled */
+};
+
+/*! \brief Flags for aum_group flag field */
+enum aum_group_flags {
+	AUM_GROUP_FLAG_REALTIME = (1 << 0),	/*!< Group loaded from realtime */
+	AUM_GROUP_FLAG_DISABLED = (1 << 1),	/*!< Group disabled */
+};
+
+
+/*! \brief Declaration of grouplist structure for inclusion in objects */
+AST_LIST_HEAD(aum_user_grouplist, aum_group_member);
+AST_LIST_HEAD(aum_user_addrlist, aum_address);
+AST_LIST_HEAD(aum_user_contextlist, aum_context);
+AST_LIST_HEAD(aum_presencelist, aum_presence);
+AST_LIST_HEAD(aum_devicelist, aum_device);
+
+/*! \brief Main AUM user object
+	\par This is the main AUM object
+	- contains linked list of addresses
+	- contains linked list of contexts of addresses
+	- contains linked list of group memberships
+*/
+struct aum_user {
+	ASTOBJ_COMPONENTS(struct aum_user);	/*!< Generic pointers - name being one. Name is not a user name, but a user ID code.
+							Only a-z and 0-9, has to begin
+							with character. Not significant in any way, just a handle us 
+						*/
+	unsigned int flags;		/*!< Flags for various stuff, see AUM_USER_FLAG_* */
+	char mailbox[AST_MAX_EXTENSION];	/*!< Default mailbox */
+	char default_exten[AST_MAX_EXTENSION];	/*!< Default extension for this user (for callbacks) */
+	char cid_num[256];		/*!< Default caller ID num (E.164 type) */
+	char cid_name[256];		/*!< Default caller ID name */
+	int calling_pres;		/*!< Default Caller ID presentation */
+	char accountcode[AST_MAX_ACCOUNT_CODE];	/*!< Default Account code */
+	char sip_username[256];		/*!< SIP user name (utf8) */
+	char musicclass[MAX_MUSICCLASS];	/*!< Default musicclass for this user */
+	char first_name[80];		/*!< First name (ISO 8859-1) */
+	char last_name[80];		/*!< Last name (ISO 8859-1) */
+	char title[20];			/*!< Title */
+	char language[MAX_LANGUAGE];	/*!< Default language */
+	char iax2privatekey[20];	/*!< Private key for this user */
+	char zonetag[80];		/*!< Time zone */
+	char numuserid[80];		/*!< Numeric user ID for this user */
+	char pincode[80];		/*!< Numeric pincode for this user */
+	char secret[80];		/*!< Secret for this user */
+	char ldapdn[180];		/*!< LDAP DN */
+	char registrar[20];		/*!< Who added this object? */
+	ast_group_t callgroup;			/*!< Calling group for calls */
+	ast_group_t pickupgroup;		/*!< Pickup group */
+	struct ast_variable *chanvars;	/*!< Default channel variables */
+	struct aum_presencelist	presence;	/*! Presence states */
+	struct aum_user_contextlist contexts;	/*!< Linked list of contexts this user use */
+	struct aum_user_grouplist groups;	/*!< Linked list of groups we are members to */
+	struct aum_user_addrlist address;	/*!< Linked list of addresses of various types */
+	struct aum_devicelist devices;		/*!< Linked list of devices active for this user */
+	struct ast_ha	*acl;			/*!< Access control list for user */
+						/*!< The highest priority is used as primary group for setting default values */
+	int managerperm;			/*!< If sat, this user can log in to manager with these permissions */
+};
+
+/*! \brief the AUM group definition */
+struct aum_group {
+	ASTOBJ_COMPONENTS(struct aum_group);	/*! Generic pointers and name field */
+	unsigned int flags;			/*!< Flags for various stuff, see AUM_GROUP_FLAG_* */
+	char sipdomain[120];			/*!< Should be AST_MAX_DOMAIN something */
+	char incoming_did[AST_MAX_EXTENSION];	/*!< Main DID for this group */
+	char language[MAX_LANGUAGE];		/*!< Default language for group */
+	char musicclass[MAX_MUSICCLASS];	/*!< Default musicclass for this group */
+	ast_group_t callgroup;			/*!< Calling group for calls */
+	ast_group_t pickupgroup;		/*!< Pickup group */
+	int managerperm;			/*!< This group's permissions in manager */
+	struct aum_user_contextlist contexts;	/*!< Linked list of contexts this group use */
+	struct ast_variable *chanvars;
+	struct ast_ha	*acl;			/*!< Access control list for user */
+	char *description;			/*!< Description */
+	struct aum_user_grouplist members;	/*!< Members list */
+	char registrar[20];		/*!< Who added this object? */
+};
+
+/*--------------------------- GLOBAL FUNCTIONS ----------------------*/
+
+/*! \brief Find AUM user 
+	\param userid Unique user ID for this user 
+	\param realtime TRUE forces lookup and loading of realtime users in memory
+	\return NULL if not found, otherwise pointer to structure 
+*/
+struct aum_user *find_aum_user(char *userid, int realtime);
+
+/*! \brief Find an address for an AUM user 
+	\param user	AUM user object pointer
+	\param type	AUM address type (enum)
+	\param start	AUM Address pointer for where to start the search in the linked list. NULL if from beginning
+	\return		Pointer to AUM address object if found, otherwise NULL 
+*/
+struct aum_address *find_address_for_user(struct aum_user *user, enum aum_address_type type, struct aum_address *start);
+
+/*! \brief Find address object for specified address
+	\param user	AUM user object pointer
+	\param type	AUM address type (enum aum_address_type)
+	\param address	Address
+	\return 	Pointer to AUM address object if found, otherwise NULL
+*/
+struct aum_address *find_user_aum_address(struct aum_user *user, enum aum_address_type type, char *address);
+
+/*! \brief Find user by any AUM address type address (xmpp, sip, email, iax2 etc)
+	\param type	AUM address type (enum)
+	\param address	Address as a text string
+*/
+struct aum_user *find_user_by_address(enum aum_address_type type, char *address);
+
+/*! \brief Find AUM user by e-mail
+	\param email Email address for this user
+	\return NULL if not found, otherwise pointer to structure 
+*/
+struct aum_user *find_aum_user_email(char *email);
+
+/*! \brief Find AUM user by numeric user id
+	\param numuid Searched numeric user ID
+	\return NULL if not found, otherwise pointer to structure
+*/
+struct aum_user *find_aum_user_by_numuserid(char *numuserid);
+
+/*! \brief Find AUM user group by group name 
+	\param Group name in text
+	\result struct aum_group pointer to group
+*/
+struct aum_group *find_aum_group_by_name(char *groupname);
+
+/*! \brief Find out if user belongs to group 
+	\param user AUM user object
+	\param group Group name
+*/
+int aum_group_test(struct aum_user *user, char *groupname);
+
+/*! \brief Find out if user belongs to group by group object
+	\param user AUM user object
+	\param group Group name
+*/
+int aum_group_test_full(struct aum_user *user, struct aum_group *group);
+
+/*! \brief Find e-mail address for AUM user
+	\param user AUM user id
+	\return E-mail address with highest priority, NULL if not found
+*/
+char *aum_find_email(char *userid);
+
+/*! \brief Find e-mail address for AUM user by AUM struct pointer
+	\param user AUM struct pointer
+	\return E-mail address with highest priority, NULL if not found
+*/
+char *aum_find_email_full(struct aum_user *user);
+
+/*! \brief Find jabber/XMPP address for AUM user
+	\param user AUM user id
+	\return Jabber/XMPP uri with highest priority, NULL if not found
+*/
+char *aum_find_xmpp(char *userid);
+
+/*! \brief Find jabber/XMPP address for AUM user by AUM struct pointer
+	\param user AUM struct pointer
+	\return Jabber/XMPP uri with highest priority, NULL if not found
+*/
+char *aum_find_xmpp_full(struct aum_user *user);
+
+/*! \brief Find any address of given type 
+	\param user AUM struct pointer
+	\param type AUM address type
+	\return Character string with highest priority, NULL if not found
+*/
+char *aum_find_address(struct aum_user *user, enum aum_address_type type);
+
+/*! \brief Find a context for a user
+	\param user AUM struct pointer
+	\param type AUM context type (enum)
+	\return character string pointer if context found, NULL if not found
+*/
+char *aum_find_user_context(struct aum_user *user, enum aum_context_type type);
+
+/*! \brief Find parking context for a user 
+	\param user AUM user struct pointer
+*/
+#define aum_find_user_parking(user)	aum_find_user_context(user, AUM_CONTEXT_PARKING);
+
+/*--------- AUM String handling functions ----------------------*/
+/*! \brief Allocate AUM string - remember to deallocate
+	\param string	Input character string
+	\param charset	aum_string_charset enum
+	\return 	aum_string object
+*/
+aum_string *aum_string_alloc(char *string, enum aum_string_charset charset);
+
+/*! \brief Convert string, allocate new aum_string object and link it at end of list
+	\param string	Input aum_string
+	\param charset	aum_string_charset enum
+	\return 	aum_string object
+*/
+aum_string *aum_string_add_charset_variant(aum_string *string, enum aum_string_charset charset);
+
+/*! \brief Get string in specific character set. If not found, convert to that charset and return string
+	\param string	Input aum_string
+	\param charset	aum_string_charset enum
+	\return 	character string (char *)
+*/
+char *aum_string_output(aum_string *string, enum aum_string_charset charset);
+
+/*! \brief Parse character set in front of string, create string
+	\param string	string optionally with charset in front of string, separated with |
+	\param defaultcharset	Default character set, if not specified
+	\return 	aum_string object, allocated by this function
+	
+*/
+aum_string *aum_string_add(char *string, enum aum_string_charset defaultcharset);
+
+/*! \brief Destroy all strings beginning with this one */
+void aum_string_destroy(aum_string *string);
+
+#endif /* _ASTERISK_MD5_H */

Modified: team/oej/aum-trunk/res/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/aum-trunk/res/Makefile?rev=7475&r1=7474&r2=7475&view=diff
==============================================================================
--- team/oej/aum-trunk/res/Makefile (original)
+++ team/oej/aum-trunk/res/Makefile Wed Dec 14 15:07:27 2005
@@ -11,7 +11,7 @@
 # the GNU General Public License
 #
 
-MODS=res_indications.so res_monitor.so res_adsi.so res_agi.so res_features.so
+MODS=res_indications.so res_monitor.so res_adsi.so res_agi.so res_features.so res_aum.so
 
 ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/odbcinst.h)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/odbcinst.h),)
   ifneq (${OSARCH},FreeBSD)
@@ -75,7 +75,7 @@
 	rm -f $(DESTDIR)$(ASTHEADERDIR)/parking.h
 	rm -f $(DESTDIR)$(MODULES_DIR)/app_agi.so 
 	rm -f $(DESTDIR)$(MODULES_DIR)/res_parking.so
-	for x in $(MODS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
+	for x in $(MODS); do ($(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR);echo Installing $$x) ; done
 	@if [ x`which mpg123 2>/dev/null | grep -v '^no'` != x ] ; then \
 	  if mpg123 --longhelp 2>&1 | grep -q .59r 2>&1 >/dev/null ; then echo ; else \
 			echo "*************************************************************";\

Added: team/oej/aum-trunk/res/res_aum.c
URL: http://svn.digium.com/view/asterisk/team/oej/aum-trunk/res/res_aum.c?rev=7475&view=auto
==============================================================================
--- team/oej/aum-trunk/res/res_aum.c (added)
+++ team/oej/aum-trunk/res/res_aum.c Wed Dec 14 15:07:27 2005
@@ -1,0 +1,1893 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * 
+ * Asterisk User Management Resource
+ *
+ * Copyright (C) 2005, Edvina AB, Sollentuna, Sweden.
+ *
+ * Olle E. Johansson <oej at edvina.net>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * 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 AUM - Asterisk User Management
+ *
+ * \author Olle E. Johansson <oej at edvina.net>
+ *
+ * \arg For information about aum, see \ref AUM_desc
+ *
+ */
+ 
+#include <pthread.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <iconv.h>	/* String conversion routines */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.19 $")
+
+#include "asterisk/lock.h"
+#include "asterisk/file.h"
+#include "asterisk/logger.h"
+#include "asterisk/config.h"
+#include "asterisk/channel.h"
+#include "asterisk/callerid.h"
+#include "asterisk/astobj.h"
+#include "asterisk/pbx.h"
+#include "asterisk/acl.h"
+#include "asterisk/options.h"
+#include "asterisk/module.h"
+#include "asterisk/app.h"
+#include "asterisk/cli.h"
+#include "asterisk/manager.h"
+#include "asterisk/utils.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/aum.h"
+
+/*! AUM user lock */
+AST_MUTEX_DEFINE_STATIC(aum_userlock);
+/*! AUM group lock */
+AST_MUTEX_DEFINE_STATIC(aum_grouplock);
+
+STANDARD_LOCAL_USER;
+
+LOCAL_USER_DECL;
+
+/*! \page AUM_desc Asterisk User Managment - AUM - module 
+	\par What is AUM?
+	The AUM module implements common user management. A user
+	can have one or several voicemail accounts, phones, IM accounts
+	and other properties. A common user module mamkes it easier
+	to manage passwords, e-mail addresses and properties that belong
+	to the person who manages a device.
+
+	\par
+	In AUM-enabled Asterisk modules (channels, applications, functions)
+	you can refer to the AUMid and thus fetch configuration data from
+	the AUM module for common properties.
+
+	\par Currently these modules support AUM:
+		- none 
+
+	\par Modules that may benefit from implementing AUM
+		- all channel drivers
+		- app_disa.c
+		- app_voicemail.c
+		- app_meetme.c
+		- manager.c
+		- The Asterisk CLI
+		- Parking
+
+	\par The AUM User object
+	The AUM user object consist of one general structure and
+	linked lists for addresses, contexts and groups.
+	When installed, the user inherit properties from the groups.
+	\arg \ref aum_user The user object
+	\arg \ref aum_group The group object
+
+	\par
+	The user has a presence state that can be checked with
+	a dial plan function. Presence can be changed from a SIP phone
+	with publish or linked to an IM account (if there's code support
+	for it).
+
+	\par The AUM Address Object
+	The address object consists of a type and a text string.
+	The type can be a phone number, SIP uri, IAX number or 
+	cell phone number.
+
+	\par The AUM group object
+	Group objects are "master" objects that the User inherits
+	properties from.
+
+	There are dial plan functions to check if a user belongs
+	to a user group or not.
+	
+	\par The AUM context object
+	...
+	\par The AUM string object
+	The AUM string object is an encapsulation of a normal C character string,
+	terminated with a zero character. It is a linked list of strings 
+	where each string is clearly marked with character set.
+	If a different character set is asked for, the string handling functions
+	will convert and add a new string in a linked list from the first one.
+
+	- String objects are created with aum_string_alloc()
+	- String objects are destroyed with aum_string_destroy()
+
+	\par Ideas for AUM presence
+	
+	Basically, we need to have a few classical PBX presence indicators
+	with major status and substatus
+	- Away
+		- Meeting
+		- Sick
+		- Travelling
+	- Meeting
+	- Busy
+	- Not reachable (system error, network error)
+	- Custom 
+		- Custom
+	- Agent specific statuses
+
+	For each user, a chain of events need to maintained, current and
+	future events. The handling of past events is up to another system.
+	
+	- For each user, we need to keep track of next planned change.
+	- For planned event changes, check whether the time is mandatory
+	  (should be executed) or a suggestion (don't time out, just keep
+	  current status while waiting for status change).
+	  Example:
+		- Meeting is planned to 13:00, but ran over to 14:15
+		- I am busy to 10:45, open my phone after that.
+	
+	- We need to store events somewhere (event silo) between reloads
+	- Events can come in trough dial plan or manager
+	- Current user status can be changed through dialplan functions,
+	  manager or IM channels/gateways (Jabber, SIP, other)
+	- We need to synch status levels with other IM (SIMPLE/Jabber/XMPP)
+
+	\par Realtime usage
+	AUM uses ARA - the realtime architecture - to load users and groups.
+	The realtime handles for AUM is
+	- \b aumusers	For users
+	- \b aumgroups  For the realtime groups
+	
+	AUM will cache realtime users in memory after we load them.
+	Every time a realtime user is accessed, it's moved to top of
+	the cache. When we reach the maximum number of cached users,
+	AUM mwill delete from the bottom of the cache while adding the
+	missing user to the top.
+	
+	(Actually, the cache is implemented upside down, but I guess
+	that does not matter.)
+
+	The AUM cache size will be configurable in the general
+	section of aum.conf
+
+	\par Channel usage
+	For channels, they can register a device that belongs to
+	a user in combination with a callback function. It that callback
+	is registred, it will be called each time a user state changes.
+
+	\par Things to do
+	- Implement all core AUM api functions from aum.h
+		- Revise the list
+	- Implement needed function in config engine (if needed)
+	- Implement manager functions for AUM
+		- Read presence
+		- Change presence
+	- Implement dial plan functions
+		- belong_to_group
+		- check_presence
+		- get_email_address
+		- get_sip_address
+	- Implement AUM in channel drivers
+		- Implement in chan_sip.c
+		- Implement in chan_iax2.c
+	- Implement AUM in applications
+		- Implement AUM in app_disa.c
+		- Implement AUM in app_voicemail.c
+	- Implement AUM functions
+		- Callback to register devices with AUM - $AUMUSERPHONE()
+	- Check if we can merge AUM with 
+		- mogorman's jabber patch
+		- file's SIP messaging patch
+	- Can we use aum_groups as callgroups/pickupgroups?
+	- Internationalization issues
+		- Learn how to use utf-8 in source code and convert between different
+	  	strings (firstname, lastname, sip uri etc)
+		- Figure out what character set is used in config and relatime
+ 	- Investigate the possibility of a chan_user as a proxy channel (ssokol's idea)
+	- Implement channel registration and callbacks
+	- Continue with other projects
+	- \b Remember: It's only software
+*/
+
+/*------------------------------- Declarations of static functions ---------*/
+enum modulereloadreason {	/* Should be in module.h or something */
+        MODULE__LOAD,
+        MODULE__RELOAD,
+        MODULE_CLI_RELOAD,
+        MODULE_MANAGER_RELOAD,
+};
+
+static void *aum_allocate(size_t size);
+static void aum_free(void *obj);
+static void aum_destroy_user(struct aum_user *user);
+static void aum_destroy_group(struct aum_group *group);
+static struct aum_user *aum_build_user(char *username, struct ast_variable *x, int realtime);
+static struct aum_group *aum_build_group(char *groupname, struct ast_variable *x, int realtime);
+const char *modulereloadreason2txt(enum modulereloadreason reason);
+static const char *aum_addrtype2txt(enum aum_address_type type);
+static enum aum_address_type get_addr_type_from_config_option(enum aum_config_options option);
+static const char *context_type2str(enum aum_context_type type);
+
+
+/*! ----------------------------------------
+\brief AUM General Configuration 
+*/
+/*! \brief Configuration file name */
+char *aum_config_file = "aum.conf";
+
+/*! \brief AUM debugging */
+int aum_debug = 0;
+
+/* Counters */
+int aum_static_users;		/*!< Number of in-memory users */
+int aum_real_users;		/*!< Number of active realtime users */
+int aum_real_groups;		/*!< Number of active realtime groups */
+int aum_static_groups;		/*!< Number of in-memory groups */
+int aum_real_groups_enabled = 0;	/*!< TRUE If realtime groups are enabled */
+int aum_real_users_enabled = 0;		/*!< TRUE if realtime users are enabled */
+
+long aum_memory_used = 0;		/*!< Used memory for the AUM module */
+
+iconv_t	ichandler_utf8_to_iso88591;	/*!< libiconv handler from utf8 to iso8859-1 */
+iconv_t	ichandler_iso88591_to_utf8;	/*!< libiconv handler from iso8859- to utf8 */
+
+/*! \brief the AUM Group list */
+static struct s_aum_grouplist {
+	ASTOBJ_CONTAINER_COMPONENTS(struct aum_group);
+} aum_grouplist;
+
+/*! \brief the AUM User list */
+static struct s_aum_userlist {
+	ASTOBJ_CONTAINER_COMPONENTS(struct aum_user);
+} aum_userlist;
+
+/*! \brief The realtime user cache */
+struct aum_usercache_struct {
+	struct aum_user *user;
+	AST_LIST_ENTRY(aum_usercache_struct) list;
+};
+
+static int aum_usercache_count = 0;	/*!< Current number of users in user cache */
+static int aum_usercache_max;		/*!< Maximum number of users in cache */
+#define DEFAULT_USERCACHE_MAX	50
+
+static AST_LIST_HEAD_STATIC(aum_usercache, aum_usercache_struct);	/*!< The user cache for realtime */
+
+/*! brief Different config options for address formats */
+static struct aum_address_config_struct aum_address_config[] = {
+	{AUM_ADDR_EMAIL, 	"email", 	"E-mail",	AUM_CNF_ADDR_EMAIL},
+	{AUM_ADDR_EMAIL, 	"mailto", 	"E-mail",	AUM_CNF_ADDR_EMAIL},
+	{AUM_ADDR_XMPP,		"xmpp", 	"XMPP/Jabber",	AUM_CNF_ADDR_XMPP},
+	{AUM_ADDR_XMPP,		"jabber", 	"XMPP/Jabber",	AUM_CNF_ADDR_XMPP},	/*! Alias for xmpp */
+	{AUM_ADDR_SIP,		"sip", 		"SIP",		AUM_CNF_ADDR_SIP},	
+	{AUM_ADDR_MSN,		"msn", 		"MSN",		AUM_CNF_ADDR_MSN},
+	{AUM_ADDR_AOL,		"aol", 		"AOL",		AUM_CNF_ADDR_AOL},
+	{AUM_ADDR_TEL,		"tel", 		"Tel",		AUM_CNF_ADDR_TEL},
+	{AUM_ADDR_TEL,		"phone", 	"Tel",		AUM_CNF_ADDR_TEL},
+	{AUM_ADDR_TEL,		"e164", 	"Tel",		AUM_CNF_ADDR_TEL},
+	{AUM_ADDR_CELL_TEL,	"cell", 	"Cell",		AUM_CNF_ADDR_CELL_TEL},
+	{AUM_ADDR_CELL_TEL,	"mobile", 	"Cell",		AUM_CNF_ADDR_CELL_TEL},
+	{AUM_ADDR_IAX2,		"iax", 		"IAX2",		AUM_CNF_ADDR_IAX2},
+	{AUM_ADDR_IAX2,		"iax2", 	"IAX2",		AUM_CNF_ADDR_IAX2},
+	{AUM_ADDR_FWD,		"fwd", 		"FWD",		AUM_CNF_ADDR_FWD},
+	{AUM_ADDR_IAXTEL,	"iaxtel", 	"IAXtel",	AUM_CNF_ADDR_IAXTEL},
+	{AUM_ADDR_FAX,		"fax", 		"Fax",		AUM_CNF_ADDR_FAX},
+	{AUM_ADDR_WEB,		"homepage", 	"Web",		AUM_CNF_ADDR_WEB},
+	{AUM_ADDR_WEB,		"url", 		"Web",		AUM_CNF_ADDR_WEB},
+	{AUM_ADDR_WEB,		"http", 	"Web",		AUM_CNF_ADDR_WEB},
+};
+
+static struct aum_context_table aum_context_text[] = {
+	{AUM_CONTEXT_NONE,		"None" },
+	{AUM_CONTEXT_DEF_CB,		"Callback" },
+	{AUM_CONTEXT_DEF_INCOMING,	"Incoming" },
+	{AUM_CONTEXT_VOICEMAIL,		"Voicemail" },
+	{AUM_CONTEXT_DISA,		"Disa" },
+	{AUM_CONTEXT_SIPSUBSCRIBE,	"SIPsubscribe" },
+};
+
+
+const char *modulereloadreason2txt(enum modulereloadreason reason)
+{
+	switch (reason) {
+	case MODULE__LOAD:	return "LOAD (Channel module load)";
+		break;
+	case MODULE__RELOAD:	return "RELOAD (Channel module reload)";
+		break;
+	case MODULE_CLI_RELOAD:	return "CLIRELOAD (Channel module reload by CLI command)";
+		break;
+	default:        	return "MANAGERRELOAD (Channel module reload by manager)";
+		break;
+        };
+};
+
+/*! \brief Convert address type to display string */
+static const char *aum_addrtype2txt(enum aum_address_type type) {
+	int x;
+	for (x = 0; x < (sizeof(aum_address_config) / sizeof(struct aum_address_config_struct)); x++) {
+		if (aum_address_config[x].type == type)
+			return aum_address_config[x].display;
+	}
+	return "";
+}
+
+/*----------------------------- CLI COMMANDS ----------------------*/
+/*! \brief  print_group: Print call group and pickup group ---*/
+static void  print_group(int fd, unsigned int group, int crlf) 
+{
+	char buf[256];
+	ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
+}
+
+
+/*! \brief CLI command description */
+static char cli_aum_show_stats_usage[] = 
+"Usage: aum show stats\n"
+"	Displays some AUM statistics.\n";
+
+/*! \brief CLI command "aum show stats" */
+static int cli_aum_show_stats(int fd, int argc, char *argv[])
+{
+
+	if (argc != 3)
+		return RESULT_SHOWUSAGE;
+	ast_cli(fd, "AUM Statistics\n");
+	ast_cli(fd, "--------------\n\n");
+	ast_cli(fd, "  Allocated memory:      %-10.10ld\n", aum_memory_used);
+	ast_cli(fd, "  Users - static:        %-10.10d\n", aum_static_users);
+	ast_cli(fd, "  Groups - static:       %-10.10d\n", aum_static_groups);
+	if (aum_real_users_enabled)
+		ast_cli(fd, "  Users - realtime:      %-10.10d\n", aum_real_users);
+	if (aum_real_groups_enabled)
+		ast_cli(fd, "  Groups - realtime:     %-10.10d\n", aum_real_groups);
+	if (aum_real_users_enabled)
+		ast_cli(fd, "  Realtime cache:        %d objects (%-10.10d kb) %d %% full\n", aum_usercache_count, (aum_usercache_count * (sizeof(struct aum_user) + sizeof(struct aum_usercache_struct)) / 1000), (aum_usercache_count / aum_usercache_max * 100 ) );
+	ast_cli(fd, "\n\n");
+	
+	return RESULT_SUCCESS;
+}
+
+/*! \brief CLI command description */
+static char cli_aum_show_users_usage[] = 
+"Usage: aum show users\n"
+"	Lists all configured AUM users.\n"
+"	For details on a specific user, use \"aum show user <name>\"\n";
+
+/*! \brief CLI command "aum show users" */
+static int cli_aum_show_users(int fd, int argc, char *argv[])
+{
+	int numusers = 0;
+
+	if (argc != 3)
+		return RESULT_SHOWUSAGE;
+
+	if (argc != 3)
+		return RESULT_SHOWUSAGE;
+	
+	ASTOBJ_CONTAINER_TRAVERSE(&aum_userlist, 1, {
+		ASTOBJ_RDLOCK(iterator);
+		if (!ast_test_flag(iterator, AUM_USER_FLAG_REALTIME)) {
+			ast_cli(fd, " %-20.20s: %-10.10s %-15.15s %-10.10s %s\n", iterator->name, iterator->first_name, iterator->last_name, iterator->numuserid, ast_test_flag(iterator, AUM_USER_FLAG_DISABLED) ? "* DISABLED *" : "");
+			numusers ++;
+		}
+		ASTOBJ_UNLOCK(iterator);
+	} );
+	ast_cli(fd, "-- Number of users: %d\n", numusers);
+	
+	return RESULT_SUCCESS;
+}
+
+static char cli_aum_load_rtuser_usage[] = 
+"Usage: aum load rtuser <user>\n"
+"	Loads a user from realtime storage into the AUM realtime cache.\n"
+"	For a list of all static users, use \"aum show users\"\n";
+
+/*! \brief Load an realtime user */
+static int cli_aum_load_rtuser(int fd, int argc, char *argv[])
+{
+	struct aum_user *user;
+	if (!aum_real_users_enabled) {
+		ast_cli(fd, "Realtime AUM is not enabled in extconfig.conf.\n");
+		return RESULT_SUCCESS;
+	}
+	if (argc != 4)
+		return RESULT_SHOWUSAGE;
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Trying to find realtime user %s to show... \n", argv[3]);
+
+	user = find_aum_user(argv[3], TRUE);
+	if (!user) {
+		ast_cli(fd, "- AUM user %s not found\n", argv[3]);
+		return RESULT_SUCCESS;
+	}
+	if (ast_test_flag(user, AUM_USER_FLAG_REALTIME)) {
+		ast_cli(fd, "User %s is not a realtime user\n", argv[3]);
+		return RESULT_SUCCESS;
+	}
+	ast_cli(fd, "* Userid %s loaded in realtime cache. \n", user->name);
+	ast_cli(fd, "  Realtime cache:        %d objects (%-10.10d kb) %d %% full\n", aum_usercache_count, (aum_usercache_count * (sizeof(struct aum_user) + sizeof(struct aum_usercache_struct)) / 1000), (aum_usercache_count / aum_usercache_max * 100 ) );
+	ast_cli(fd, "\n");
+}
+
+/*! \brief CLI command description */
+static char cli_aum_show_user_usage[] = 
+"Usage: aum show user <user>\n"
+"	Lists details about one AUM user, either static or a realtime user in the realtime cache.\n"
+"	To load a user in the realtime cache, use \"aum load rtuser\"\n"
+"	For a list of all static users, use \"aum show users\"\n";
+
+/*! \brief CLI command "aum show user" */
+static int cli_aum_show_user(int fd, int argc, char *argv[])
+{
+	struct aum_group_member *member;
+	struct aum_context *context;
+	struct aum_address *addr;
+	struct aum_user *user;
+
+	if (argc != 4)
+		return RESULT_SHOWUSAGE;
+	ast_log(LOG_DEBUG, "Trying to find user %s to show... \n", argv[3]);
+
+	user = find_aum_user(argv[3], FALSE);
+	if (!user) {
+		ast_cli(fd, "- AUM user %s not found\n", argv[3]);
+		return RESULT_SUCCESS;
+	}
+	ast_cli(fd, "* Userid:        %s\n", user->name);
+
+	if (ast_test_flag(user, AUM_USER_FLAG_REALTIME))
+		ast_cli(fd, " Usertype:   Realtime (cached)\n");
+	else
+		ast_cli(fd, " Usertype:   Static\n");
+
+	if (ast_test_flag(user, AUM_USER_FLAG_DISABLED))
+		ast_cli(fd, " Status:     Disabled\n");
+	else
+		ast_cli(fd, " Status:     Enabled\n");
+
+	if (!ast_strlen_zero(user->title))
+		ast_cli(fd, " Title:      %s\n", user->title);
+	if (!ast_strlen_zero(user->last_name))
+		ast_cli(fd, " Name:       %s %s\n", user->first_name, user->last_name);
+	
+	AST_LIST_TRAVERSE(&user->groups, member, list) {
+		ast_cli(fd, " Member of:  %s\n", member->group->name);
+	};
+
+	AST_LIST_TRAVERSE(&user->address, addr, list) {
+		ast_cli(fd, " Address:    %s - %s\n", aum_addrtype2txt(addr->type), addr->address);
+	};
+
+	AST_LIST_TRAVERSE(&user->contexts, context, list) {
+		ast_cli(fd, " %s Context : %s\n", context_type2str(context->type), context->context);
+	};
+	ast_cli(fd, "  Callgroup:     ");
+	print_group(fd, user->callgroup, 0);
+	ast_cli(fd, "  Pickupgroup:   ");
+	print_group(fd, user->pickupgroup, 0);
+	ast_cli(fd, " Numeric ID :    %s\n", user->numuserid);
+	ast_cli(fd, " Secret :        %s\n", !ast_strlen_zero(user->secret) ? "<set>" : "<not set>");
+	ast_cli(fd, " Music class:    %s\n", user->musicclass);
+	ast_cli(fd, " Language:       %s\n", user->language);
+	ast_cli(fd, " Mailbox:        %s\n", user->mailbox);
+	ast_cli(fd, " ACL:            %s\n", (user->acl?"Yes (IP address restriction)":"No"));
+	if (user->chanvars) {
+		struct ast_variable *v;
+ 		ast_cli(fd, "  Variables    :\n");
+		for (v = user->chanvars ; v ; v = v->next)
+ 			ast_cli(fd, "                 %s = %s\n", v->name, v->value);
+	}
+	ast_cli(fd,"\n");
+	
+	return RESULT_SUCCESS;
+}
+

[... 1375 lines stripped ...]


More information about the asterisk-commits mailing list