[asterisk-commits] branch oej/aum - r7302 in /team/oej/aum:
include/asterisk/aum.h res/res_aum.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sat Dec 3 11:40:29 CST 2005
Author: oej
Date: Sat Dec 3 11:40:26 2005
New Revision: 7302
URL: http://svn.digium.com/view/asterisk?rev=7302&view=rev
Log:
The resource file and include file, more info in doxygen :-) This is work in progress.
Added:
team/oej/aum/include/asterisk/aum.h
team/oej/aum/res/res_aum.c
Added: team/oej/aum/include/asterisk/aum.h
URL: http://svn.digium.com/view/asterisk/team/oej/aum/include/asterisk/aum.h?rev=7302&view=auto
==============================================================================
--- team/oej/aum/include/asterisk/aum.h (added)
+++ team/oej/aum/include/asterisk/aum.h Sat Dec 3 11:40:26 2005
@@ -1,0 +1,411 @@
+/*
+ * 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 See also
+ * \arg AUM_desc
+ */
+
+#ifndef _ASTERISK_AUM_H
+#define _ASTERISK_AUM_H
+
+/*--------------------------- 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_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_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_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 */
+};
+
+/*! \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 */
+};
+
+/*! \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 */
+};
+
+/*! \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 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);
+
+/*! \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 */
+ 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 */
+ 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 */
+ struct aum_presencelist presence; /*! Presence states */
+ 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? */
+ struct ast_variable *chanvars; /*!< Default channel variables */
+ 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 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 */
+ int calling_pres; /*!< Default Caller ID presentation */
+};
+
+/*! \brief the AUM group definition */
+struct aum_group {
+ ASTOBJ_COMPONENTS(struct aum_group);
+ 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 */
+ int managerperm; /*!< This group's permissions in manager */
+ struct aum_user_contextlist contexts; /*!< Linked list of contexts this group use */
+ struct ast_variable *chanvars;
+ char *description; /*!< Description */
+ struct aum_user_grouplist members;
+};
+
+/*--------------------------- GLOBAL FUNCTIONS ----------------------*/
+
+/*! \brief Find AUM user
+ \param userid Unique user ID for this user
+ \return NULL if not found, otherwise pointer to structure
+*/
+struct aum_user *find_aum_user(char *userid);
+
+/*! \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_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);
+
+/*--------- 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 */
Added: team/oej/aum/res/res_aum.c
URL: http://svn.digium.com/view/asterisk/team/oej/aum/res/res_aum.c?rev=7302&view=auto
==============================================================================
--- team/oej/aum/res/res_aum.c (added)
+++ team/oej/aum/res/res_aum.c Sat Dec 3 11:40:26 2005
@@ -1,0 +1,1478 @@
+/*
+ * 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/astobj.h"
+#include "asterisk/pbx.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 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
+ - 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= 0; /*!< Number of in-memory users */
+int aum_real_users= 0; /*!< Number of active realtime users */
+int aum_real_groups = 0; /*!< Number of active realtime groups */
+int aum_static_groups = 0; /*!< 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 Group list */
+static struct s_aum_grouplist {
+ ASTOBJ_CONTAINER_COMPONENTS(struct aum_group);
+} aum_grouplist;
+
+/*! \brief the User list */
+static struct s_aum_userlist {
+ ASTOBJ_CONTAINER_COMPONENTS(struct aum_user);
+} aum_userlist;
+
+/*! 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 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);
+ 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;
+ int numgroups = 0;
+
+ if (argc != 3)
+ return RESULT_SHOWUSAGE;
+
+ ASTOBJ_CONTAINER_TRAVERSE(&aum_userlist, 1, {
+ ASTOBJ_RDLOCK(iterator);
+ ast_cli(fd, " %-20.20s \n", iterator->name);
+ numusers ++;
+ ASTOBJ_UNLOCK(iterator);
+ } );
+ ast_cli(fd, "-- Number of users: %d\n", numusers);
+
+ return RESULT_SUCCESS;
+}
+
+/*! \brief CLI command description */
+static char cli_aum_show_user_usage[] =
+"Usage: aum show user <user>\n"
+" Lists details about one AUM user.\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_address *addr;
+ struct aum_context *context;
+ 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]);
+ if (!user) {
+ ast_cli(fd, "- AUM user %s not found\n", argv[3]);
+ return RESULT_SUCCESS;
+ }
+ ast_cli(fd, "* Userid: %s\n", user->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);
+ };
+
+ return RESULT_SUCCESS;
+}
+
+/*! \brief CLI command description */
+static char cli_aum_show_groups_usage[] =
+"Usage: aum show groups\n"
+" Lists all configured AUM groups.\n"
+" For details on a specific group, use \"aum show group <name>\"\n";
+
+
+/*! \brief CLI command "aum show groups" */
+static int cli_aum_show_groups(int fd, int argc, char *argv[])
+{
+ int numgroups = 0;
+
+ if (argc != 3)
+ return RESULT_SHOWUSAGE;
+
+ ASTOBJ_CONTAINER_TRAVERSE(&aum_grouplist, 1, {
+ ASTOBJ_RDLOCK(iterator);
+ ast_cli(fd, " %-20.20s %55s\n", iterator->name, (iterator->description ? iterator->description : "") );
+ numgroups ++;
+ ASTOBJ_UNLOCK(iterator);
+ } );
+
+ ast_cli(fd, "-- %d AUM groups\n\n", numgroups);
+
+ return RESULT_SUCCESS;
+}
+
+
+
+/*! \brief CLI entries for the AUM module */
+static struct ast_cli_entry my_clis[] = {
+ { { "aum", "show", "groups", NULL }, cli_aum_show_groups, "List AUM groups", cli_aum_show_groups_usage },
+ { { "aum", "show", "users", NULL }, cli_aum_show_users, "List AUM users", cli_aum_show_users_usage },
+ { { "aum", "show", "user", NULL }, cli_aum_show_user, "List details of AUM user", cli_aum_show_user_usage },
+ { { "aum", "show", "stats", NULL }, cli_aum_show_stats, "Display AUM statistics", cli_aum_show_stats_usage },
+};
+
+/*----------------------------- DIALPLAN FUNCTIONS ---------------------*/
+static char *func_aumuser_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ struct aum_user *user;
+ char *s, *args[2];
+ char *username, *param;
+ int error = 0;
+ char *res = NULL;
+
+ buf[0] = '\0'; /* Reset buffer */
+
+ if (!data) {
+ error = 1;
+ } else {
+ s = ast_strdupa((char *) data);
+ if (!s) {
+ error = 1;
+ } else {
+ ast_app_separate_args(s, '|', args, 2);
+ username = args[0];
+ param = args[1];
+ if (!param)
+ error = 1;
+ }
+ }
+
+ if (error) {
+ ast_log(LOG_ERROR, "This function requires two parameters.\n");
+ return (char*) NULL;
+ }
+ user = find_aum_user(username);
+ if (!user) {
+ ast_log(LOG_ERROR, "AUM user ID %s not found.\n", username);
+ return (char*) NULL;
+ }
+ if (!strcasecmp(param, "email")) {
+ res = aum_find_email_full(user);
+ } else if (!strcasecmp(param, "xmpp")) {
+ res = aum_find_address(user, AUM_ADDR_XMPP);
+ } else if (!strcasecmp(param, "sip")) {
+ res = aum_find_address(user, AUM_ADDR_SIP);
+ } else if (!strcasecmp(param, "tel")) {
+ res = aum_find_address(user, AUM_ADDR_TEL);
+ } else if (!strcasecmp(param, "iax2")) {
+ res = aum_find_address(user, AUM_ADDR_IAX2);
+ } else if (!strcasecmp(param, "fwd")) {
+ res = aum_find_address(user, AUM_ADDR_FWD);
+ } else if (!strcasecmp(param, "numuserid")) {
+ res = user->numuserid;
+ } else if (!strcasecmp(param, "pincode")) {
+ res = user->pincode;
+ } else if (!strcasecmp(param, "firstname")) {
+ res = user->first_name;
+ } else if (!strcasecmp(param, "lastname")) {
+ res = user->first_name;
+ } else if (!strcasecmp(param, "title")) {
+ res = user->title;
+ } else if (!strcasecmp(param, "musicclass")) {
+ res = user->musicclass;
+ } else if (!strcasecmp(param, "language")) {
+ res = user->language;
+ } else if (!strcasecmp(param, "accountcode")) {
+ res = user->accountcode;
+ } else if (!strcasecmp(param, "cidnum")) {
+ res = user->cid_num;
+ } else if (!strcasecmp(param, "cidname")) {
+ res = user->cid_name;
+ } else if (!strcasecmp(param, "name")) {
+ snprintf(buf, sizeof(buf), "%s %s", user->first_name, user->last_name);
+ } else if (!strcasecmp(param, "vmbox")) {
+ snprintf(buf, sizeof(buf), "%s@%s", user->mailbox, aum_find_user_context(user, AUM_CONTEXT_VOICEMAIL));
+ } else {
+ ast_log(LOG_ERROR, "Unknown parameter: %s\n", param);
+ return (char*) NULL;
+ }
+
+ if (res)
+ ast_copy_string(buf, res, len);
+ return buf;
+}
+
+/*! Dial plan function AUM-USER */
+struct ast_custom_function aum_user_function = {
+ .name = "AUM-USER",
+ .synopsis = "Gets AUM User information",
+ .syntax = "AUM-USER(<userid>,<param>)",
+ .read = func_aumuser_read,
+ .desc = "Valid parameters are:\n"
+ "- name First and last name\n"
+ "- firstname First name\n"
+ "- lastname Last name\n"
+ "- email Email address\n"
+ "- xmpp XMPP/Jabber address\n"
+ "- sip SIP address\n"
+ "- tel Telephone number\n"
+ "- iax2 IAX2 address\n"
+ "- fwd FWD number\n"
+ "- numuserid Numeric User ID\n"
+ "- pincode User's Pincode\n"
+ "- musicclass Default music class (MOH)\n"
+ "- accountcode Account code\n"
+ "- vmbox Voicemail box for user (mbox at vmcontext)\n"
+ "- cidnum Caller ID number\n"
+ "- cidname Caller ID name\n"
+ "\n",
+};
+
+/*-------------------------AUM_STRING SUPPORT--------------------------*/
+static struct aum_string_convert aum_string_labels[] = {
+ { AUM_CHAR_ASCII, "ASCII" },
+ { AUM_CHAR_ISO8859_1, "ISO8859-1" },
+ { AUM_CHAR_ISO8859_2, "ISO8859-2" },
+ { AUM_CHAR_ISO8859_3, "ISO8859-3" },
+ { AUM_CHAR_UTF8, "UTF8" },
+};
+
+aum_string *aum_string_alloc(char *string, enum aum_string_charset charset)
+{
+ aum_string *temp = NULL;
+ if (!string || charset == AUM_CHAR_UNKNOWN)
+ return temp; /* Null */
+
+ temp = (aum_string *) aum_allocate(sizeof(aum_string));
+ temp->charset = charset;
+ temp->string = strdup(string);
+ temp->size = sizeof(temp->string);
+ aum_memory_used += (long) temp->size;
+
+ return temp;
+}
+
+void aum_string_destroy(aum_string *string)
+{
+ aum_free(string->string);
+ aum_free(string);
+}
+
+aum_string *aum_string_add_charset_variant(aum_string *string, enum aum_string_charset charset)
+{
+ aum_string *temp = string;
+ aum_string *new = (aum_string *) NULL;
+ char buf[BUFSIZ];
+ size_t newsize = 0, insize, outsize;
+ enum aum_string_charset fromcharset;
+ char *inbuf;
+
+ while (temp && temp->charset != charset)
+ temp = (aum_string *) temp->next;
+
+ if (temp) /* We got a string already */
+ return temp;
+
+ fromcharset = string->charset;
+ insize = sizeof(string->string);
+ outsize = sizeof(buf);
+ inbuf = string->string;
+ if (fromcharset == AUM_CHAR_UTF8) {
+ switch (charset) {
+ case AUM_CHAR_ISO8859_1:
+ newsize = iconv(ichandler_utf8_to_iso88591, &inbuf, &insize, &buf, &outsize);
+ break;
+ case AUM_CHAR_ASCII:
+ ast_log(LOG_DEBUG, "Don't know how to convert from utf to ascii yet...\n");
+ break;
+ default:
+ ast_log(LOG_DEBUG, "Don't know how to convert from utf to unknown charset yet...\n");
+ break;
+ }
+ } else if (fromcharset == AUM_CHAR_ISO8859_1) {
+ switch (charset) {
+ case AUM_CHAR_UTF8:
+ newsize = iconv(ichandler_iso88591_to_utf8, &inbuf, &insize, &buf, &outsize);
+ break;
+ case AUM_CHAR_ASCII:
+ ast_log(LOG_DEBUG, "Don't know how to convert from ISO8859-1 to ascii yet...\n");
+ break;
+ default:
+ ast_log(LOG_DEBUG, "Don't know how to convert from utf to unknown charset yet...\n");
+ break;
+ }
+ }
+ if (newsize == (size_t) -1) /* Could not convert */
+ /* If errno == EILSEQ Illegal multibyte sequence */
+ /* If errno == EINVAL Invalid multibyte sequence */
+ /* If errno == E2BIG Output buffer too small */
+ return temp; /* ??? */
+
+ new = aum_string_alloc(buf, charset); /* Allocate object */
+
+ /* Link it in */
+ temp = string->next;
+ string->next = new;
+ new->next = temp;
+
+ return new;
+
+}
+
+//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 */
+// char *aum_string_output(aum_string *string, enum aum_string_charset charset);
+// aum_string *aum_string_add(char *string, enum aum_string_charset defaultcharset);
+
+/*------------------------- CONFIGURATION ------------------------------*/
+static struct aum_config_struct aum_config[] = {
+ { AUM_CNF_ADDR_EMAIL, "email" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_XMPP, "xmpp" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_XMPP, "jabber" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_SIP, "sip" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_IAX2, "iax" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_AOL, "aol" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_MSN, "msn" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_TEL, "tel" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_CELL_TEL,"cell" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_ADDR_FAX, "fax" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_PIN, "pin" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_VMAILBOX, "mailbox" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_GROUP, "group" ,AUM_CONFOBJ_USER },
+ { AUM_CNF_CALLBACKEXT, "extension" ,AUM_CONFOBJ_USER }, /*!< Default extension */
+ { AUM_CNF_DEFCONTEXT, "context" ,AUM_CONFOBJ_USER & AUM_CONFOBJ_GROUP },
+ { AUM_CNF_SUBSCRIBECONTEXT, "subscribecontext" ,AUM_CONFOBJ_USER & AUM_CONFOBJ_GROUP },
+ { AUM_CNF_DISACONTEXT, "disacontext" ,AUM_CONFOBJ_USER & AUM_CONFOBJ_GROUP },
[... 817 lines stripped ...]
More information about the asterisk-commits
mailing list