Files
asterisk/include/asterisk/calendar.h
Ludovic Gasc (GMLudo) 9f62feca60 res_calendar: Add support for fetching calendars when reloading
We use a lot res_calendar, we are very happy with that, especially
because you use libical, the almost alone opensource library that
supports really ical format with all types of recurrency.

Nevertheless, some features are missed for our business use cases.

This first patch adds a new option in calendar.conf:
fetch_again_at_reload. Be my guest for a better name.

If it's true, when you'll launch "module reload res_calendar.so",
Asterisk will download again the calendar.

The business use case is that we have a WebUI with a scheduler planner,
we know when the calendars are modified.

For now, we need to define 1 minute of timeout to have a chance that
our user doesn't wait too long between the modification and the real
test.  But it generates a lot of useless HTTP traffic.


ASTERISK-26422 #close

Change-Id: I384b02ebfa42b142bbbd5b7221458c7f4dee7077
2016-10-10 10:43:53 -05:00

207 lines
7.7 KiB
C

/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2008 - 2009, Digium, Inc.
*
* Terry Wilson <twilson@digium.com>
*
* 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.
*/
#ifndef _ASTERISK_CALENDAR_H
#define _ASTERISK_CALENDAR_H
#include "asterisk.h"
#include "asterisk/stringfields.h"
#include "asterisk/config.h"
#include "asterisk/linkedlists.h"
#include "asterisk/lock.h"
#include "asterisk/dial.h"
#include "asterisk/module.h"
/*! \file calendar.h
* \brief A general API for managing calendar events with Asterisk
*
* \author Terry Wilson <twilson@digium.com>
*
* \note This API implements an abstraction for handling different calendaring
* technologies in Asterisk. The services provided by the API are a dialplan
* function to query whether or not a calendar is busy at the present time, a
* adialplan function to query specific information about events in a time range,
* a devicestate provider, and notification of calendar events through execution
* of dialplan apps or dialplan logic at a specific context and extension. The
* information available through the CALENDAR_EVENT() dialplan function are:
*
* SUMMARY, DESCRIPTION, ORGANIZER, LOCATION
* CALENDAR, UID, START, END, and BUSYSTATE
*
* BUSYSTATE can have the values 0 (free), 1 (tentatively busy), or 2 (busy)
*
* Usage
* All calendaring configuration data is located in calendar.conf and is only read
* directly by the Calendaring API. Each calendar technology resource must register
* a load_calendar callback which will be passed an ast_calendar_load_data structure.
* The load_calendar callback function should then set the values it needs from this
* cfg, load the calendar data, and then loop updating the calendar data and events
* baesd on the refresh interval in the ast_calendar object. Each call to
* the load_calendar callback will be will run in its own thread.
*
* Updating events involves creating an astobj2 container of new events and passing
* it to the API through ast_calendar_merge_events.
*
* Calendar technology resource modules must also register an unref_calendar callback
* which will only be called when the resource module calls ast_calendar_unregister()
* to unregister that module's calendar type (usually done in module_unload())
*/
struct ast_calendar;
struct ast_calendar_event;
/*! \brief Individual calendaring technology data */
struct ast_calendar_tech {
const char *type;
const char *description;
const char *module;
struct ast_module_user *user;
int (* is_busy)(struct ast_calendar *calendar); /*!< Override default busy determination */
void *(* load_calendar)(void *data); /*!< Create private structure, add calendar events, etc. */
void *(* unref_calendar)(void *obj); /*!< Function to be called to free the private structure */
int (* write_event)(struct ast_calendar_event *event); /*!< Function for writing an event to the calendar */
AST_LIST_ENTRY(ast_calendar_tech) list;
};
enum ast_calendar_busy_state {
AST_CALENDAR_BS_FREE = 0,
AST_CALENDAR_BS_BUSY_TENTATIVE,
AST_CALENDAR_BS_BUSY,
};
struct ast_calendar_attendee {
char *data;
AST_LIST_ENTRY(ast_calendar_attendee) next;
};
/* \brief Calendar events */
struct ast_calendar_event {
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(summary);
AST_STRING_FIELD(description);
AST_STRING_FIELD(organizer);
AST_STRING_FIELD(location);
AST_STRING_FIELD(uid);
AST_STRING_FIELD(categories);
);
int priority; /*!< Priority of event */
struct ast_calendar *owner; /*!< The calendar that owns this event */
time_t start; /*!< Start of event (UTC) */
time_t end; /*!< End of event (UTC) */
time_t alarm; /*!< Time for event notification */
enum ast_calendar_busy_state busy_state; /*!< The busy status of the event */
int notify_sched; /*!< The sched for event notification */
int bs_start_sched; /*!< The sched for changing the device state at the start of an event */
int bs_end_sched; /*!< The sched for changing the device state at the end of an event */
struct ast_dial *dial;
struct ast_channel *notify_chan;
AST_LIST_HEAD_NOLOCK(attendees, ast_calendar_attendee) attendees;
};
/*! \brief Asterisk calendar structure */
struct ast_calendar {
const struct ast_calendar_tech *tech;
void *tech_pvt;
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(name); /*!< Name from config file [name] */
AST_STRING_FIELD(notify_channel); /*!< Channel to use for notification */
AST_STRING_FIELD(notify_context); /*!< Optional context to execute from for notification */
AST_STRING_FIELD(notify_extension); /*!< Optional extension to execute from for notification */
AST_STRING_FIELD(notify_app); /*!< Optional dialplan app to execute for notification */
AST_STRING_FIELD(notify_appdata); /*!< Optional arguments for dialplan app */
);
struct ast_variable *vars; /*!< Channel variables to pass to notification channel */
int autoreminder; /*!< If set, override any calendar_tech specific notification times and use this time (in mins) */
int notify_waittime; /*!< Maxiumum time to allow for a notification attempt */
int refresh; /*!< When to refresh the calendar events */
int fetch_again_at_reload; /*!< To reload the calendar content when the module is reloaded */
int timeframe; /*!< Span (in mins) of calendar data to pull with each request */
pthread_t thread; /*!< The thread that the calendar is loaded/updated in */
ast_cond_t unload;
int unloading:1;
int pending_deletion:1;
struct ao2_container *events; /*!< The events that are known at this time */
};
/*! \brief Register a new calendar technology
*
* \param tech calendar technology to register
*
* \retval 0 success
* \retval -1 failure
*/
int ast_calendar_register(struct ast_calendar_tech *tech);
/*! \brief Unregister a new calendar technology
*
* \param tech calendar technology to unregister
*
* \retval 0 success
* \retval -1 failure
*/
void ast_calendar_unregister(struct ast_calendar_tech *tech);
/*! \brief Allocate an astobj2 ast_calendar_event object
*
* \param cal calendar to allocate an event for
*
* \return a new, initialized calendar event
*/
struct ast_calendar_event *ast_calendar_event_alloc(struct ast_calendar *cal);
/*! \brief Allocate an astobj2 container for ast_calendar_event objects
*
* \return a new event container
*/
struct ao2_container *ast_calendar_event_container_alloc(void);
/*! \brief Add an event to the list of events for a calendar
*
* \param cal calendar containing the events to be merged
* \param new_events an oa2 container of events to be merged into cal->events
*/
void ast_calendar_merge_events(struct ast_calendar *cal, struct ao2_container *new_events);
/*! \brief Unreference an ast_calendar_event
*
* \param event event to unref
*
* \return NULL
*/
struct ast_calendar_event *ast_calendar_unref_event(struct ast_calendar_event *event);
/*! \brief Remove all events from calendar
*
* \param cal calendar whose events need to be cleared
*/
void ast_calendar_clear_events(struct ast_calendar *cal);
/*! \brief Grab and lock pointer to the calendar config (read only)
*
* \note ast_calendar_config_release must be called when finished with the pointer
*
* \return the parsed calendar config
*/
const struct ast_config *ast_calendar_config_acquire(void);
/*! \brief Release the calendar config
*/
void ast_calendar_config_release(void);
#endif /* _ASTERISK_CALENDAR_H */