Calendaring API. More...
#include "asterisk.h"#include "asterisk/_private.h"#include "asterisk/calendar.h"#include "asterisk/utils.h"#include "asterisk/astobj2.h"#include "asterisk/module.h"#include "asterisk/config.h"#include "asterisk/channel.h"#include "asterisk/devicestate.h"#include "asterisk/linkedlists.h"#include "asterisk/sched.h"#include "asterisk/dial.h"#include "asterisk/cli.h"#include "asterisk/pbx.h"#include "asterisk/app.h"
Go to the source code of this file.
Data Structures | |
| struct | evententry |
| struct | eventlist |
| struct | techs |
Defines | |
| #define | CALENDAR_BUCKETS 19 |
| #define | FORMAT "%-20.20s %-10.10s %-6.6s\n" |
| #define | FORMAT "%-10.10s %-30.30s\n" |
| #define | FORMAT "%-17.17s : %-20.20s\n" |
| #define | FORMAT2 "%-12.12s: %-40.60s\n" |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | add_event_to_list (struct eventlist *events, struct ast_calendar_event *event, time_t start, time_t end) |
| static int | add_new_event_cb (void *obj, void *arg, int flags) |
| void | ast_calendar_clear_events (struct ast_calendar *cal) |
| Remove all events from calendar. | |
| struct ast_config * | ast_calendar_config_acquire (void) |
| Grab and lock pointer to the calendar config (read only) | |
| void | ast_calendar_config_release (void) |
| Release the calendar config. | |
| struct ast_calendar_event * | ast_calendar_event_alloc (struct ast_calendar *cal) |
| Allocate an astobj2 ast_calendar_event object. | |
| struct ao2_container * | ast_calendar_event_container_alloc (void) |
| Allocate an astobj2 container for ast_calendar_event objects. | |
| void | ast_calendar_merge_events (struct ast_calendar *cal, struct ao2_container *new_events) |
| Add an event to the list of events for a calendar. | |
| int | ast_calendar_register (struct ast_calendar_tech *tech) |
| Register a new calendar technology. | |
| struct ast_calendar_event * | ast_calendar_unref_event (struct ast_calendar_event *event) |
| Unreference an ast_calendar_event. | |
| void | ast_calendar_unregister (struct ast_calendar_tech *tech) |
| Unregister a new calendar technology. | |
| static struct ast_calendar * | build_calendar (struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech) |
| static int | calendar_busy_callback (void *obj, void *arg, int flags) |
| static int | calendar_busy_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| A dialplan function that can be used to determine the busy status of a calendar. | |
| static int | calendar_cmp_fn (void *obj, void *arg, int flags) |
| static void | calendar_destructor (void *obj) |
| static int | calendar_devstate_change (const void *data) |
| static void | calendar_event_destructor (void *obj) |
| static int | calendar_event_notify (const void *data) |
| static int | calendar_event_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | calendar_hash_fn (const void *obj, const int flags) |
| static int | calendar_is_busy (struct ast_calendar *cal) |
| static void | calendar_join_attendees (struct ast_calendar_event *event, char *buf, size_t len) |
| static int | calendar_query_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | calendar_query_result_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | calendar_write_exec (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
| static enum ast_device_state | calendarstate (const char *data) |
| static int | cb_pending_deletion (void *user_data, void *arg, int flags) |
| static int | cb_rm_pending_deletion (void *user_data, void *arg, int flags) |
| static int | clear_events_cb (void *user_data, void *arg, int flags) |
| static void | copy_event_data (struct ast_calendar_event *dst, struct ast_calendar_event *src) |
| static struct ast_calendar_event * | destroy_event (struct ast_calendar_event *event) |
| static void * | do_notify (void *data) |
| static void * | do_refresh (void *data) |
| static char * | epoch_to_string (char *buf, size_t buflen, time_t epoch) |
| static int | event_cmp_fn (void *obj, void *arg, int flags) |
| static int | event_hash_fn (const void *obj, const int flags) |
| static void | event_notification_destroy (void *data) |
| static void * | event_notification_duplicate (void *data) |
| static void | eventlist_destroy (void *data) |
| static void | eventlist_destructor (void *obj) |
| static void * | eventlist_duplicate (void *data) |
| static struct ast_calendar * | find_calendar (const char *name) |
| static struct ast_calendar_event * | find_event (struct ao2_container *events, const char *uid) |
| static char * | generate_random_string (char *buf, size_t size) |
| Generate 32 byte random string (stolen from chan_sip.c) | |
| static char * | handle_dump_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_show_calendar (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_show_calendars (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list available calendars. | |
| static char * | handle_show_calendars_types (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list of all calendars types currently loaded on the backend. | |
| static int | load_config (int reload) |
| static int | load_module (void) |
| static int | load_tech_calendars (struct ast_calendar_tech *tech) |
| static int | match_caltech_cb (void *user_data, void *arg, int flags) |
| static int | merge_events_cb (void *obj, void *arg, int flags) |
| static int | null_chan_write (struct ast_channel *chan, struct ast_frame *frame) |
| static int | reload (void) |
| static int | schedule_calendar_event (struct ast_calendar *cal, struct ast_calendar_event *old_event, struct ast_calendar_event *cmp_event) |
| static int | unload_module (void) |
| static struct ast_calendar * | unref_calendar (struct ast_calendar *cal) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Calendar integration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_custom_function | calendar_busy_function |
| static struct ast_cli_entry | calendar_cli [] |
| static struct ast_config * | calendar_config |
| static struct ast_custom_function | calendar_event_function |
| static struct ast_custom_function | calendar_query_function |
| static struct ast_custom_function | calendar_query_result_function |
| static struct ast_custom_function | calendar_write_function |
| static struct ao2_container * | calendars |
| static ast_rwlock_t | config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } |
| static struct ast_datastore_info | event_notification_datastore |
| static struct ast_datastore_info | eventlist_datastore_info |
| static int | module_unloading |
| static struct ast_channel_tech | null_tech |
| static ast_cond_t | refresh_condition |
| static pthread_t | refresh_thread = AST_PTHREADT_NULL |
| static ast_mutex_t | refreshlock |
| static ast_mutex_t | reloadlock |
| static struct ast_sched_context * | sched |
| static struct techs | techs |
Calendaring API.
Support responding to a meeting invite
Support writing attendees
Definition in file res_calendar.c.
| #define CALENDAR_BUCKETS 19 |
Definition at line 211 of file res_calendar.c.
Referenced by ast_calendar_event_container_alloc(), build_calendar(), and load_module().
| #define FORMAT "%-20.20s %-10.10s %-6.6s\n" |
| #define FORMAT "%-10.10s %-30.30s\n" |
| #define FORMAT "%-17.17s : %-20.20s\n" |
| #define FORMAT2 "%-12.12s: %-40.60s\n" |
| static void __reg_module | ( | void | ) | [static] |
Definition at line 1884 of file res_calendar.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1884 of file res_calendar.c.
| static int add_event_to_list | ( | struct eventlist * | events, |
| struct ast_calendar_event * | event, | ||
| time_t | start, | ||
| time_t | end | ||
| ) | [static] |
Definition at line 1080 of file res_calendar.c.
References ao2_ref, ast_calloc, ast_debug, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_calendar_event::end, evententry::event, evententry::list, LOG_ERROR, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.
Referenced by calendar_query_exec().
{
struct evententry *entry, *iter;
int event_startdiff = abs(start - event->start);
int event_enddiff = abs(end - event->end);
int i = 0;
if (!(entry = ast_calloc(1, sizeof(*entry)))) {
ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
return -1;
}
entry->event = event;
ao2_ref(event, +1);
if (start == end) {
AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) {
int startdiff = abs(iter->event->start - start);
ast_debug(10, "Comparing %s with startdiff %d to %s with startdiff %d\n", event->summary, event_startdiff, iter->event->summary, startdiff);
++i;
if (startdiff > event_startdiff) {
AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
return i;
}
if (startdiff == event_startdiff) {
int enddiff = abs(iter->event->end - end);
if (enddiff > event_enddiff) {
AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
return i;
}
if (event_startdiff == enddiff) {
if (strcmp(event->uid, iter->event->uid) < 0) {
AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
return i;
}
}
}
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_INSERT_TAIL(events, entry, list);
return i;
}
AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) {
++i;
if (iter->event->start > event->start) {
AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
return i;
}
if (iter->event->start == event->start) {
if ((iter->event->end - iter->event->start) == (event->end - event->start)) {
if (strcmp(event->uid, iter->event->uid) < 0) {
AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
return i;
}
}
if ((iter->event->end - iter->event->start) < (event->end - event->start)) {
AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
return i;
}
}
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_INSERT_TAIL(events, entry, list);
return i;
}
| static int add_new_event_cb | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 1004 of file res_calendar.c.
References ao2_link, CMP_MATCH, events, ast_calendar_event::owner, and schedule_calendar_event().
Referenced by ast_calendar_merge_events().
{
struct ast_calendar_event *new_event = obj;
struct ao2_container *events = arg;
ao2_link(events, new_event);
schedule_calendar_event(new_event->owner, new_event, NULL);
return CMP_MATCH;
}
| void ast_calendar_clear_events | ( | struct ast_calendar * | cal | ) |
Remove all events from calendar.
| cal | calendar whose events need to be cleared |
Definition at line 632 of file res_calendar.c.
References ao2_callback, ast_debug, clear_events_cb(), ast_calendar::events, ast_calendar::name, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
Referenced by calendar_destructor().
{
ast_debug(3, "Clearing all events for calendar %s\n", cal->name);
ao2_callback(cal->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, clear_events_cb, NULL);
}
| struct ast_config* ast_calendar_config_acquire | ( | void | ) | [read] |
Grab and lock pointer to the calendar config (read only)
Definition at line 249 of file res_calendar.c.
References ast_rwlock_rdlock, ast_rwlock_unlock, and calendar_config.
Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().
{
ast_rwlock_rdlock(&config_lock);
if (!calendar_config) {
ast_rwlock_unlock(&config_lock);
return NULL;
}
return calendar_config;
}
| void ast_calendar_config_release | ( | void | ) |
Release the calendar config.
Definition at line 261 of file res_calendar.c.
References ast_rwlock_unlock, and config_lock.
Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().
{
ast_rwlock_unlock(&config_lock);
}
| struct ast_calendar_event* ast_calendar_event_alloc | ( | struct ast_calendar * | cal | ) | [read] |
Allocate an astobj2 ast_calendar_event object.
| cal | calendar to allocate an event for |
Definition at line 639 of file res_calendar.c.
References ao2_alloc, ast_calendar_unref_event(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_calendar_event::attendees, calendar_event_destructor(), and evententry::event.
Referenced by caldav_add_event(), calendar_write_exec(), icalendar_add_event(), parse_tag(), and startelm().
{
struct ast_calendar_event *event;
if (!(event = ao2_alloc(sizeof(*event), calendar_event_destructor))) {
return NULL;
}
if (ast_string_field_init(event, 32)) {
event = ast_calendar_unref_event(event);
return NULL;
}
event->owner = cal;
event->notify_sched = -1;
event->bs_start_sched = -1;
event->bs_end_sched = -1;
AST_LIST_HEAD_INIT_NOLOCK(&event->attendees);
return event;
}
| struct ao2_container* ast_calendar_event_container_alloc | ( | void | ) | [read] |
Allocate an astobj2 container for ast_calendar_event objects.
Definition at line 661 of file res_calendar.c.
References ao2_container_alloc, CALENDAR_BUCKETS, event_cmp_fn(), and event_hash_fn().
Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().
{
return ao2_container_alloc(CALENDAR_BUCKETS, event_hash_fn, event_cmp_fn);
}
| void ast_calendar_merge_events | ( | struct ast_calendar * | cal, |
| struct ao2_container * | new_events | ||
| ) |
Add an event to the list of events for a calendar.
| cal | calendar containing the events to be merged |
| new_events | an oa2 container of events to be merged into cal->events |
Definition at line 1014 of file res_calendar.c.
References add_new_event_cb(), ao2_callback, ast_calendar::events, merge_events_cb(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
Referenced by endelm(), icalendar_update_events(), startelm(), update_caldav(), and update_exchangecal().
{
/* Loop through all events attached to the calendar. If there is a matching new event
* merge its data over and handle any schedule changes that need to be made. Then remove
* the new_event from new_events so that we are left with only new_events that we can add later. */
ao2_callback(cal->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, merge_events_cb, new_events);
/* Now, we should only have completely new events in new_events. Loop through and add them */
ao2_callback(new_events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, add_new_event_cb, cal->events);
}
| int ast_calendar_register | ( | struct ast_calendar_tech * | tech | ) |
Register a new calendar technology.
| tech | calendar technology to register |
| 0 | success |
| -1 | failure |
Definition at line 526 of file res_calendar.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_module_user_add, ast_verb, ast_calendar_tech::description, evententry::list, load_tech_calendars(), LOG_WARNING, ast_calendar_tech::type, and ast_calendar_tech::user.
Referenced by load_module().
{
struct ast_calendar_tech *iter;
AST_LIST_LOCK(&techs);
AST_LIST_TRAVERSE(&techs, iter, list) {
if(!strcasecmp(tech->type, iter->type)) {
ast_log(LOG_WARNING, "Already have a handler for calendar type '%s'\n", tech->type);
AST_LIST_UNLOCK(&techs);
return -1;
}
}
AST_LIST_INSERT_HEAD(&techs, tech, list);
tech->user = ast_module_user_add(NULL);
AST_LIST_UNLOCK(&techs);
ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description);
return load_tech_calendars(tech);
}
| struct ast_calendar_event* ast_calendar_unref_event | ( | struct ast_calendar_event * | event | ) | [read] |
Unreference an ast_calendar_event.
| event | event to unref |
Definition at line 312 of file res_calendar.c.
References ao2_ref.
Referenced by ast_calendar_event_alloc(), caldav_add_event(), calendar_devstate_change(), calendar_query_exec(), calendar_write_exec(), do_notify(), endelm(), event_notification_destroy(), handle_show_calendar(), icalendar_add_event(), merge_events_cb(), and parse_tag().
{
ao2_ref(event, -1);
return NULL;
}
| void ast_calendar_unregister | ( | struct ast_calendar_tech * | tech | ) |
Unregister a new calendar technology.
| tech | calendar technology to unregister |
| 0 | success |
| -1 | failure |
Definition at line 559 of file res_calendar.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_module_user_remove, ast_verb, evententry::list, match_caltech_cb(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_calendar_tech::type, and ast_calendar_tech::user.
Referenced by load_tech_calendars(), and unload_module().
{
struct ast_calendar_tech *iter;
AST_LIST_LOCK(&techs);
AST_LIST_TRAVERSE_SAFE_BEGIN(&techs, iter, list) {
if (iter != tech) {
continue;
}
ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, match_caltech_cb, tech);
AST_LIST_REMOVE_CURRENT(list);
ast_module_user_remove(iter->user);
ast_verb(2, "Unregistered calendar type '%s'\n", tech->type);
break;
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&techs);
}
| static struct ast_calendar* build_calendar | ( | struct ast_config * | cfg, |
| const char * | cat, | ||
| const struct ast_calendar_tech * | tech | ||
| ) | [static, read] |
Definition at line 394 of file res_calendar.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_unlink, ast_cond_init, ast_free, ast_log(), ast_pthread_create, AST_PTHREADT_NULL, ast_strdup, ast_string_field_init, ast_string_field_set, ast_strip(), ast_variable_browse(), ast_variable_new(), ast_calendar::autoreminder, CALENDAR_BUCKETS, calendar_destructor(), event_cmp_fn(), event_hash_fn(), ast_calendar::events, find_calendar(), last, ast_calendar_tech::load_calendar, LOG_ERROR, LOG_WARNING, name, ast_variable::name, ast_variable::next, ast_calendar::notify_waittime, ast_calendar::pending_deletion, ast_calendar::refresh, ast_calendar::tech, ast_calendar::thread, ast_calendar::timeframe, ast_calendar::unload, unref_calendar(), value, ast_variable::value, var, and ast_calendar::vars.
Referenced by load_tech_calendars().
{
struct ast_calendar *cal;
struct ast_variable *v, *last = NULL;
int new_calendar = 0;
if (!(cal = find_calendar(cat))) {
new_calendar = 1;
if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) {
ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n");
return NULL;
}
if (!(cal->events = ao2_container_alloc(CALENDAR_BUCKETS, event_hash_fn, event_cmp_fn))) {
ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat);
cal = unref_calendar(cal);
return NULL;
}
if (ast_string_field_init(cal, 32)) {
ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat);
cal = unref_calendar(cal);
return NULL;
}
} else {
cal->pending_deletion = 0;
}
ast_string_field_set(cal, name, cat);
cal->tech = tech;
cal->refresh = 3600;
cal->timeframe = 60;
cal->notify_waittime = 30000;
for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
if (!strcasecmp(v->name, "autoreminder")) {
cal->autoreminder = atoi(v->value);
} else if (!strcasecmp(v->name, "channel")) {
ast_string_field_set(cal, notify_channel, v->value);
} else if (!strcasecmp(v->name, "context")) {
ast_string_field_set(cal, notify_context, v->value);
} else if (!strcasecmp(v->name, "extension")) {
ast_string_field_set(cal, notify_extension, v->value);
} else if (!strcasecmp(v->name, "waittime")) {
int i = atoi(v->value);
if (i > 0) {
cal->notify_waittime = 1000 * i;
}
} else if (!strcasecmp(v->name, "app")) {
ast_string_field_set(cal, notify_app, v->value);
} else if (!strcasecmp(v->name, "appdata")) {
ast_string_field_set(cal, notify_appdata, v->value);
} else if (!strcasecmp(v->name, "refresh")) {
cal->refresh = atoi(v->value);
} else if (!strcasecmp(v->name, "timeframe")) {
cal->timeframe = atoi(v->value);
} else if (!strcasecmp(v->name, "setvar")) {
char *name, *value;
struct ast_variable *var;
if ((name = (value = ast_strdup(v->value)))) {
strsep(&value, "=");
if (value) {
if ((var = ast_variable_new(ast_strip(name), ast_strip(value), ""))) {
if (last) {
last->next = var;
} else {
cal->vars = var;
}
last = var;
}
} else {
ast_log(LOG_WARNING, "Malformed argument. Should be '%s: variable=value'\n", v->name);
}
ast_free(name);
}
}
}
if (new_calendar) {
cal->thread = AST_PTHREADT_NULL;
ast_cond_init(&cal->unload, NULL);
ao2_link(calendars, cal);
if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) {
/* If we start failing to create threads, go ahead and return NULL
* and the tech module will be unregistered
*/
ao2_unlink(calendars, cal);
cal = unref_calendar(cal);
}
}
return cal;
}
| static int calendar_busy_callback | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 352 of file res_calendar.c.
References AST_CALENDAR_BS_FREE, ast_tvnow(), ast_calendar_event::busy_state, CMP_STOP, ast_calendar_event::end, evententry::event, and ast_calendar_event::start.
Referenced by calendar_is_busy().
{
struct ast_calendar_event *event = obj;
int *is_busy = arg;
struct timeval tv = ast_tvnow();
if (tv.tv_sec >= event->start && tv.tv_sec <= event->end && event->busy_state > AST_CALENDAR_BS_FREE) {
*is_busy = 1;
return CMP_STOP;
}
return 0;
}
| static int calendar_busy_exec | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
A dialplan function that can be used to determine the busy status of a calendar.
Definition at line 1053 of file res_calendar.c.
References ast_log(), ast_strlen_zero(), calendar_is_busy(), find_calendar(), LOG_WARNING, and unref_calendar().
{
struct ast_calendar *cal;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n");
return -1;
}
cal = find_calendar(data);
if (!cal) {
ast_log(LOG_WARNING, "Could not find calendar '%s'\n", data);
return -1;
}
strcpy(buf, calendar_is_busy(cal) ? "1" : "0");
cal = unref_calendar(cal);
return 0;
}
| static int calendar_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 278 of file res_calendar.c.
References CMP_MATCH, CMP_STOP, and ast_calendar::name.
Referenced by load_module().
{
const struct ast_calendar *one = obj, *two = arg;
return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP: 0;
}
| static void calendar_destructor | ( | void * | obj | ) | [static] |
Definition at line 318 of file res_calendar.c.
References ao2_lock, ao2_ref, ao2_unlock, ast_calendar_clear_events(), ast_cond_signal, ast_debug, ast_string_field_free_memory, ast_variables_destroy(), ast_calendar::events, ast_calendar::name, ast_calendar::tech, ast_calendar::tech_pvt, ast_calendar::thread, ast_calendar::unload, ast_calendar::unloading, ast_calendar_tech::unref_calendar, and ast_calendar::vars.
Referenced by build_calendar().
{
struct ast_calendar *cal = obj;
ast_debug(3, "Destroying calendar %s\n", cal->name);
ao2_lock(cal);
cal->unloading = 1;
ast_cond_signal(&cal->unload);
pthread_join(cal->thread, NULL);
if (cal->tech_pvt) {
cal->tech_pvt = cal->tech->unref_calendar(cal->tech_pvt);
}
ast_calendar_clear_events(cal);
ast_string_field_free_memory(cal);
if (cal->vars) {
ast_variables_destroy(cal->vars);
cal->vars = NULL;
}
ao2_ref(cal->events, -1);
ao2_unlock(cal);
}
| static int calendar_devstate_change | ( | const void * | data | ) | [static] |
Definition at line 853 of file res_calendar.c.
References ao2_ref, ast_calendar_unref_event(), AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_tvnow(), calendar_is_busy(), evententry::event, LOG_WARNING, ast_calendar::name, and ast_calendar_event::owner.
Referenced by schedule_calendar_event().
{
struct ast_calendar_event *event = (struct ast_calendar_event *)data;
struct timeval now = ast_tvnow();
int is_end_event;
if (!event) {
ast_log(LOG_WARNING, "Event was NULL!\n");
return 0;
}
ao2_ref(event, +1);
is_end_event = event->end <= now.tv_sec;
if (is_end_event) {
event->bs_end_sched = -1;
} else {
event->bs_start_sched = -1;
}
/* We can have overlapping events, so ignore the event->busy_state and check busy state
* based on all events in the calendar */
if (!calendar_is_busy(event->owner)) {
ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
} else {
ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
}
event = ast_calendar_unref_event(event);
return 0;
}
| static void calendar_event_destructor | ( | void * | obj | ) | [static] |
Definition at line 581 of file res_calendar.c.
References ast_debug, ast_free, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_calendar_event::attendees, ast_calendar_attendee::data, evententry::event, ast_calendar::name, evententry::next, and ast_calendar_event::owner.
Referenced by ast_calendar_event_alloc().
{
struct ast_calendar_event *event = obj;
struct ast_calendar_attendee *attendee;
ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name);
ast_string_field_free_memory(event);
while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) {
if (attendee->data) {
ast_free(attendee->data);
}
ast_free(attendee);
}
}
| static int calendar_event_notify | ( | const void * | data | ) | [static] |
Definition at line 829 of file res_calendar.c.
References ao2_ref, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, do_notify(), evententry::event, LOG_ERROR, and ast_calendar_event::owner.
Referenced by schedule_calendar_event().
{
struct ast_calendar_event *event = (void *)data;
int res = -1;
pthread_t notify_thread = AST_PTHREADT_NULL;
if (!(event && event->owner)) {
ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
return res;
}
ao2_ref(event, +1);
event->notify_sched = -1;
if (ast_pthread_create_background(¬ify_thread, NULL, do_notify, event) < 0) {
ast_log(LOG_ERROR, "Could not create notification thread\n");
return res;
}
res = 0;
return res;
}
| static int calendar_event_read | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 1671 of file res_calendar.c.
References ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_calendar_event::busy_state, calendar_join_attendees(), ast_calendar_event::categories, ast_datastore::data, ast_calendar_event::description, ast_calendar_event::end, evententry::event, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.
{
struct ast_datastore *datastore;
struct ast_calendar_event *event;
if (!chan) {
ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
return -1;
}
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "%s requires an argument\n", cmd);
return -1;
}
ast_channel_lock(chan);
if (!(datastore = ast_channel_datastore_find(chan, &event_notification_datastore, NULL))) {
ast_log(LOG_WARNING, "There is no event notification datastore on '%s'!\n", ast_channel_name(chan));
ast_channel_unlock(chan);
return -1;
}
ast_channel_unlock(chan);
if (!(event = datastore->data)) {
ast_log(LOG_WARNING, "The datastore contains no data!\n");
return -1;
}
if (!strcasecmp(data, "summary")) {
ast_copy_string(buf, event->summary, len);
} else if (!strcasecmp(data, "description")) {
ast_copy_string(buf, event->description, len);
} else if (!strcasecmp(data, "organizer")) {
ast_copy_string(buf, event->organizer, len);
} else if (!strcasecmp(data, "location")) {
ast_copy_string(buf, event->location, len);
} else if (!strcasecmp(data, "categories")) {
ast_copy_string(buf, event->categories, len);
} else if (!strcasecmp(data, "priority")) {
snprintf(buf, len, "%d", event->priority);
} else if (!strcasecmp(data, "calendar")) {
ast_copy_string(buf, event->owner->name, len);
} else if (!strcasecmp(data, "uid")) {
ast_copy_string(buf, event->uid, len);
} else if (!strcasecmp(data, "start")) {
snprintf(buf, len, "%ld", (long)event->start);
} else if (!strcasecmp(data, "end")) {
snprintf(buf, len, "%ld", (long)event->end);
} else if (!strcasecmp(data, "busystate")) {
snprintf(buf, len, "%d", event->busy_state);
} else if (!strcasecmp(data, "attendees")) {
calendar_join_attendees(event, buf, len);
}
return 0;
}
| static int calendar_hash_fn | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 272 of file res_calendar.c.
References ast_str_case_hash(), and ast_calendar::name.
Referenced by load_module().
{
const struct ast_calendar *cal = obj;
return ast_str_case_hash(cal->name);
}
| static int calendar_is_busy | ( | struct ast_calendar * | cal | ) | [static] |
Definition at line 366 of file res_calendar.c.
References ao2_callback, calendar_busy_callback(), ast_calendar::events, and OBJ_NODATA.
Referenced by calendar_busy_exec(), calendar_devstate_change(), calendarstate(), destroy_event(), and handle_show_calendars().
{
int is_busy = 0;
ao2_callback(cal->events, OBJ_NODATA, calendar_busy_callback, &is_busy);
return is_busy;
}
| static void calendar_join_attendees | ( | struct ast_calendar_event * | event, |
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 1265 of file res_calendar.c.
References ast_copy_string(), ast_free, AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_calendar_event::attendees, ast_calendar_attendee::data, LOG_ERROR, and evententry::next.
Referenced by calendar_event_read(), and calendar_query_result_exec().
{
struct ast_str *tmp;
struct ast_calendar_attendee *attendee;
if (!(tmp = ast_str_create(32))) {
ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n");
return;
}
AST_LIST_TRAVERSE(&event->attendees, attendee, next) {
ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data);
}
ast_copy_string(buf, ast_str_buffer(tmp), len);
ast_free(tmp);
}
| static int calendar_query_exec | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 1174 of file res_calendar.c.
References add_event_to_list(), ao2_alloc, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, args, AST_APP_ARG, ast_calendar_unref_event(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc(), ast_debug, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_calendar_event::end, evententry::event, eventlist_destructor(), events, ast_calendar::events, find_calendar(), generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_calendar_event::start, ast_calendar_event::summary, and unref_calendar().
{
struct ast_calendar *cal;
struct ao2_iterator i;
struct ast_calendar_event *event;
struct eventlist *events;
time_t start = INT_MIN, end = INT_MAX;
struct ast_datastore *eventlist_datastore;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(calendar);
AST_APP_ARG(start);
AST_APP_ARG(end);
);
if (!chan) {
ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd);
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
if (ast_strlen_zero(args.calendar)) {
ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd);
return -1;
}
if (!(cal = find_calendar(args.calendar))) {
ast_log(LOG_WARNING, "Unknown calendar '%s'\n", args.calendar);
return -1;
}
if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) {
ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
cal = unref_calendar(cal);
return -1;
}
if (!ast_strlen_zero(args.start)) {
start = atoi(args.start);
}
if (!ast_strlen_zero(args.end)) {
end = atoi(args.end);
}
i = ao2_iterator_init(cal->events, 0);
while ((event = ao2_iterator_next(&i))) {
if (!(start > event->end || end < event->start)) {
ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end);
if (add_event_to_list(events, event, start, end) < 0) {
event = ast_calendar_unref_event(event);
cal = unref_calendar(cal);
ao2_ref(events, -1);
ao2_iterator_destroy(&i);
return -1;
}
}
event = ast_calendar_unref_event(event);
}
ao2_iterator_destroy(&i);
ast_channel_lock(chan);
do {
generate_random_string(buf, len);
} while (ast_channel_datastore_find(chan, &eventlist_datastore_info, buf));
ast_channel_unlock(chan);
if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) {
ast_log(LOG_ERROR, "Could not allocate datastore!\n");
cal = unref_calendar(cal);
ao2_ref(events, -1);
return -1;
}
eventlist_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
eventlist_datastore->data = events;
ast_channel_lock(chan);
ast_channel_datastore_add(chan, eventlist_datastore);
ast_channel_unlock(chan);
cal = unref_calendar(cal);
return 0;
}
| static int calendar_query_result_exec | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 1283 of file res_calendar.c.
References args, AST_APP_ARG, ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_calendar_event::busy_state, calendar_join_attendees(), ast_calendar_event::categories, ast_datastore::data, ast_calendar_event::description, ast_calendar_event::end, evententry::event, events, evententry::list, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.
{
struct ast_datastore *datastore;
struct eventlist *events;
struct evententry *entry;
int row = 1;
size_t listlen = 0;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(id);
AST_APP_ARG(field);
AST_APP_ARG(row);
);
if (!chan) {
ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
return -1;
}
AST_STANDARD_APP_ARGS(args, data);
if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) {
ast_log(LOG_WARNING, "%s requires an id and a field", cmd);
return -1;
}
ast_channel_lock(chan);
if (!(datastore = ast_channel_datastore_find(chan, &eventlist_datastore_info, args.id))) {
ast_log(LOG_WARNING, "There is no event notification datastore with id '%s' on '%s'!\n", args.id, ast_channel_name(chan));
ast_channel_unlock(chan);
return -1;
}
ast_channel_unlock(chan);
if (!(events = datastore->data)) {
ast_log(LOG_WARNING, "The datastore contains no data!\n");
return -1;
}
if (!ast_strlen_zero(args.row)) {
row = atoi(args.row);
}
AST_LIST_TRAVERSE(events, entry, list) {
listlen++;
}
if (!strcasecmp(args.field, "getnum")) {
snprintf(buf, len, "%zu", listlen);
return 0;
}
AST_LIST_TRAVERSE(events, entry, list) {
if (--row) {
continue;
}
if (!strcasecmp(args.field, "summary")) {
ast_copy_string(buf, entry->event->summary, len);
} else if (!strcasecmp(args.field, "description")) {
ast_copy_string(buf, entry->event->description, len);
} else if (!strcasecmp(args.field, "organizer")) {
ast_copy_string(buf, entry->event->organizer, len);
} else if (!strcasecmp(args.field, "location")) {
ast_copy_string(buf, entry->event->location, len);
} else if (!strcasecmp(args.field, "categories")) {
ast_copy_string(buf, entry->event->categories, len);
} else if (!strcasecmp(args.field, "priority")) {
snprintf(buf, len, "%d", entry->event->priority);
} else if (!strcasecmp(args.field, "calendar")) {
ast_copy_string(buf, entry->event->owner->name, len);
} else if (!strcasecmp(args.field, "uid")) {
ast_copy_string(buf, entry->event->uid, len);
} else if (!strcasecmp(args.field, "start")) {
snprintf(buf, len, "%ld", (long) entry->event->start);
} else if (!strcasecmp(args.field, "end")) {
snprintf(buf, len, "%ld", (long) entry->event->end);
} else if (!strcasecmp(args.field, "busystate")) {
snprintf(buf, len, "%d", entry->event->busy_state);
} else if (!strcasecmp(args.field, "attendees")) {
calendar_join_attendees(entry->event, buf, len);
} else {
ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field);
}
break;
}
return 0;
}
| static int calendar_write_exec | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| const char * | value | ||
| ) | [static] |
Definition at line 1376 of file res_calendar.c.
References AST_APP_ARG, ast_calendar_event_alloc(), ast_calendar_unref_event(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_STANDARD_APP_ARGS, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), ast_calendar_event::end, evententry::event, find_calendar(), LOG_ERROR, LOG_WARNING, ast_calendar::name, pbx_builtin_setvar_helper(), ast_calendar_event::start, ast_calendar::tech, unref_calendar(), and ast_calendar_tech::write_event.
{
int i, j, ret = -1;
char *val_dup = NULL;
struct ast_calendar *cal = NULL;
struct ast_calendar_event *event = NULL;
struct timeval tv = ast_tvnow();
AST_DECLARE_APP_ARGS(fields,
AST_APP_ARG(field)[10];
);
AST_DECLARE_APP_ARGS(values,
AST_APP_ARG(value)[10];
);
if (!(val_dup = ast_strdup(value))) {
ast_log(LOG_ERROR, "Could not allocate memory for values\n");
goto write_cleanup;
}
AST_STANDARD_APP_ARGS(fields, data);
AST_STANDARD_APP_ARGS(values, val_dup);
/* XXX Eventually we will support unnamed calendars, so if we don't find one, we parse
* for a calendar type and create it */
if (!(cal = find_calendar(fields.field[0]))) {
ast_log(LOG_WARNING, "Couldn't find calendar '%s'\n", fields.field[0]);
goto write_cleanup;
}
if (!(cal->tech->write_event)) {
ast_log(LOG_WARNING, "Calendar '%s' has no write function!\n", cal->name);
goto write_cleanup;
}
if (!(event = ast_calendar_event_alloc(cal))) {
goto write_cleanup;
}
if (ast_strlen_zero(fields.field[0])) {
ast_log(LOG_WARNING, "CALENDAR_WRITE requires a calendar name!\n");
goto write_cleanup;
}
if (fields.argc - 1 != values.argc) {
ast_log(LOG_WARNING, "CALENDAR_WRITE should have the same number of fields (%d) and values (%d)!\n", fields.argc - 1, values.argc);
goto write_cleanup;
}
event->owner = cal;
for (i = 1, j = 0; i < fields.argc; i++, j++) {
if (!strcasecmp(fields.field[i], "summary")) {
ast_string_field_set(event, summary, values.value[j]);
} else if (!strcasecmp(fields.field[i], "description")) {
ast_string_field_set(event, description, values.value[j]);
} else if (!strcasecmp(fields.field[i], "organizer")) {
ast_string_field_set(event, organizer, values.value[j]);
} else if (!strcasecmp(fields.field[i], "location")) {
ast_string_field_set(event, location, values.value[j]);
} else if (!strcasecmp(fields.field[i], "categories")) {
ast_string_field_set(event, categories, values.value[j]);
} else if (!strcasecmp(fields.field[i], "priority")) {
event->priority = atoi(values.value[j]);
} else if (!strcasecmp(fields.field[i], "uid")) {
ast_string_field_set(event, uid, values.value[j]);
} else if (!strcasecmp(fields.field[i], "start")) {
event->start = atoi(values.value[j]);
} else if (!strcasecmp(fields.field[i], "end")) {
event->end = atoi(values.value[j]);
} else if (!strcasecmp(fields.field[i], "busystate")) {
event->busy_state = atoi(values.value[j]);
} else {
ast_log(LOG_WARNING, "Unknown calendar event field '%s'\n", fields.field[i]);
}
}
if (!event->start) {
event->start = tv.tv_sec;
}
if (!event->end) {
event->end = tv.tv_sec;
}
if((ret = cal->tech->write_event(event))) {
ast_log(LOG_WARNING, "Writing event to calendar '%s' failed!\n", cal->name);
}
write_cleanup:
if (ret) {
pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "0");
} else {
pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "1");
}
if (cal) {
cal = unref_calendar(cal);
}
if (event) {
event = ast_calendar_unref_event(event);
}
if (val_dup) {
ast_free(val_dup);
}
return ret;
}
| static enum ast_device_state calendarstate | ( | const char * | data | ) | [static] |
Definition at line 375 of file res_calendar.c.
References AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, ast_strlen_zero(), calendar_is_busy(), find_calendar(), ast_calendar_tech::is_busy, state, ast_calendar::tech, and unref_calendar().
Referenced by load_module().
{
enum ast_device_state state;
struct ast_calendar *cal;
if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) {
return AST_DEVICE_INVALID;
}
if (cal->tech->is_busy) {
state = cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
} else {
state = calendar_is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
}
cal = unref_calendar(cal);
return state;
}
| static int cb_pending_deletion | ( | void * | user_data, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 1734 of file res_calendar.c.
References CMP_MATCH, and ast_calendar::pending_deletion.
Referenced by reload().
{
struct ast_calendar *cal = user_data;
cal->pending_deletion = 1;
return CMP_MATCH;
}
| static int cb_rm_pending_deletion | ( | void * | user_data, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 1743 of file res_calendar.c.
References CMP_MATCH, and ast_calendar::pending_deletion.
Referenced by reload().
{
struct ast_calendar *cal = user_data;
return cal->pending_deletion ? CMP_MATCH : 0;
}
| static int clear_events_cb | ( | void * | user_data, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 623 of file res_calendar.c.
References CMP_MATCH, destroy_event(), and evententry::event.
Referenced by ast_calendar_clear_events().
{
struct ast_calendar_event *event = user_data;
event = destroy_event(event);
return CMP_MATCH;
}
| static void copy_event_data | ( | struct ast_calendar_event * | dst, |
| struct ast_calendar_event * | src | ||
| ) | [static] |
Definition at line 887 of file res_calendar.c.
References ast_calendar_event::alarm, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_string_field_set, ast_calendar_event::attendees, ast_calendar_event::busy_state, ast_calendar_event::categories, ast_calendar_event::description, ast_calendar_event::end, ast_calendar_event::location, evententry::next, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.
Referenced by merge_events_cb().
{
struct ast_calendar_attendee *attendee;
ast_string_field_set(dst, summary, src->summary);
ast_string_field_set(dst, description, src->description);
ast_string_field_set(dst, organizer, src->organizer);
ast_string_field_set(dst, location, src->location);
ast_string_field_set(dst, uid, src->uid);
ast_string_field_set(dst, categories, src->categories);
dst->priority = src->priority;
dst->owner = src->owner;
dst->start = src->start;
dst->end = src->end;
dst->alarm = src->alarm;
dst->busy_state = src->busy_state;
/* Delete any existing attendees */
while ((attendee = AST_LIST_REMOVE_HEAD(&dst->attendees, next))) {
ast_free(attendee);
}
/* Copy over the new attendees */
while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) {
AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next);
}
}
| static struct ast_calendar_event* destroy_event | ( | struct ast_calendar_event * | event | ) | [static, read] |
Definition at line 598 of file res_calendar.c.
References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_sched_del(), ast_calendar_event::bs_end_sched, ast_calendar_event::bs_start_sched, calendar_is_busy(), ast_calendar::name, ast_calendar_event::notify_sched, and ast_calendar_event::owner.
Referenced by clear_events_cb(), and merge_events_cb().
{
if (event->notify_sched > -1 && ast_sched_del(sched, event->notify_sched)) {
ast_debug(3, "Notification running, can't delete sched entry\n");
}
if (event->bs_start_sched > -1 && ast_sched_del(sched, event->bs_start_sched)) {
ast_debug(3, "Devicestate update (start) running, can't delete sched entry\n");
}
if (event->bs_end_sched > -1 && ast_sched_del(sched, event->bs_end_sched)) {
ast_debug(3, "Devicestate update (end) running, can't delete sched entry\n");
}
/* If an event is being deleted and we've fired an event changing the status at the beginning,
* but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
if (!calendar_is_busy(event->owner)) {
ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
} else {
ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
}
}
return NULL;
}
| static void* do_notify | ( | void * | data | ) | [static] |
Definition at line 712 of file res_calendar.c.
References ao2_ref, ast_calendar_unref_event(), ast_channel_alloc(), ast_channel_context_set(), ast_channel_datastore_add(), ast_channel_exten_set(), ast_channel_lock, ast_channel_nativeformats(), ast_channel_priority_set(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_channel_readformat(), ast_channel_release(), ast_channel_tech_set(), ast_channel_unlock, ast_channel_writeformat(), ast_datastore_alloc(), ast_dial_answered_steal(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), AST_DIAL_OPTION_ANSWER_EXEC, ast_dial_option_global_enable(), AST_DIAL_RESULT_ANSWERED, ast_dial_run(), ast_dial_set_global_timeout(), ast_format_cap_set(), ast_format_set(), AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_pbx_run(), AST_STATE_DOWN, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_substitute_variables(), ast_strlen_zero(), ast_verb, ast_datastore::data, DATASTORE_INHERIT_FOREVER, evententry::event, generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_calendar::name, ast_variable::next, ast_calendar::notify_app, ast_calendar::notify_appdata, ast_calendar::notify_channel, ast_calendar::notify_context, ast_calendar::notify_extension, ast_calendar::notify_waittime, null_tech, ast_calendar_event::owner, pbx_builtin_setvar_helper(), ast_variable::value, and ast_calendar::vars.
Referenced by calendar_event_notify().
{
struct ast_calendar_event *event = data;
struct ast_dial *dial = NULL;
struct ast_str *apptext = NULL, *tmpstr = NULL;
struct ast_datastore *datastore;
enum ast_dial_result res;
struct ast_channel *chan = NULL;
struct ast_variable *itervar;
char *tech, *dest;
char buf[8];
tech = ast_strdupa(event->owner->notify_channel);
if ((dest = strchr(tech, '/'))) {
*dest = '\0';
dest++;
} else {
ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
goto notify_cleanup;
}
if (!(dial = ast_dial_create())) {
ast_log(LOG_ERROR, "Could not create dial structure\n");
goto notify_cleanup;
}
if (ast_dial_append(dial, tech, dest) < 0) {
ast_log(LOG_ERROR, "Could not append channel\n");
goto notify_cleanup;
}
ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
generate_random_string(buf, sizeof(buf));
if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "Calendar/%s-%s", event->owner->name, buf))) {
ast_log(LOG_ERROR, "Could not allocate notification channel\n");
goto notify_cleanup;
}
ast_channel_tech_set(chan, &null_tech);
ast_format_set(ast_channel_writeformat(chan), AST_FORMAT_SLINEAR, 0);
ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR, 0);
ast_format_set(ast_channel_rawwriteformat(chan), AST_FORMAT_SLINEAR, 0);
ast_format_set(ast_channel_rawreadformat(chan), AST_FORMAT_SLINEAR, 0);
/* clear native formats and set to slinear. write format is signlear so just use that to set it */
ast_format_cap_set(ast_channel_nativeformats(chan), ast_channel_writeformat(chan));
if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) {
ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
goto notify_cleanup;
}
datastore->data = event;
datastore->inheritance = DATASTORE_INHERIT_FOREVER;
ao2_ref(event, +1);
ast_channel_lock(chan);
res = ast_channel_datastore_add(chan, datastore);
ast_channel_unlock(chan);
if (!(tmpstr = ast_str_create(32))) {
goto notify_cleanup;
}
for (itervar = event->owner->vars; itervar; itervar = itervar->next) {
ast_str_substitute_variables(&tmpstr, 0, chan, itervar->value);
pbx_builtin_setvar_helper(chan, itervar->name, tmpstr->str);
}
if (!(apptext = ast_str_create(32))) {
goto notify_cleanup;
}
if (!ast_strlen_zero(event->owner->notify_app)) {
ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata);
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, ast_str_buffer(apptext));
} else {
}
ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name);
res = ast_dial_run(dial, chan, 0);
if (res != AST_DIAL_RESULT_ANSWERED) {
ast_verb(3, "Notification call for %s was not completed\n", event->owner->name);
} else {
struct ast_channel *answered;
answered = ast_dial_answered_steal(dial);
if (ast_strlen_zero(event->owner->notify_app)) {
ast_channel_context_set(answered, event->owner->notify_context);
ast_channel_exten_set(answered, event->owner->notify_extension);
ast_channel_priority_set(answered, 1);
ast_pbx_run(answered);
}
}
notify_cleanup:
if (apptext) {
ast_free(apptext);
}
if (tmpstr) {
ast_free(tmpstr);
}
if (dial) {
ast_dial_destroy(dial);
}
if (chan) {
ast_channel_release(chan);
}
event = ast_calendar_unref_event(event);
return NULL;
}
| static void* do_refresh | ( | void * | data | ) | [static] |
Definition at line 1776 of file res_calendar.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), and ast_tvnow().
Referenced by load_module().
{
for (;;) {
struct timeval now = ast_tvnow();
struct timespec ts = {0,};
int wait;
ast_mutex_lock(&refreshlock);
while (!module_unloading) {
if ((wait = ast_sched_wait(sched)) < 0) {
wait = 1000;
}
ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
if (ast_cond_timedwait(&refresh_condition, &refreshlock, &ts) == ETIMEDOUT) {
break;
}
}
ast_mutex_unlock(&refreshlock);
if (module_unloading) {
break;
}
ast_sched_runq(sched);
}
return NULL;
}
| static char* epoch_to_string | ( | char * | buf, |
| size_t | buflen, | ||
| time_t | epoch | ||
| ) | [static] |
Definition at line 1548 of file res_calendar.c.
References ast_localtime(), and ast_strftime().
Referenced by handle_show_calendar().
{
struct ast_tm tm;
struct timeval tv = {
.tv_sec = epoch,
};
if (!epoch) {
*buf = '\0';
return buf;
}
ast_localtime(&tv, &tm, NULL);
ast_strftime(buf, buflen, "%F %r %z", &tm);
return buf;
}
| static int event_cmp_fn | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 298 of file res_calendar.c.
References CMP_MATCH, CMP_STOP, and ast_calendar_event::uid.
Referenced by ast_calendar_event_container_alloc(), and build_calendar().
{
const struct ast_calendar_event *one = obj, *two = arg;
return !strcmp(one->uid, two->uid) ? CMP_MATCH | CMP_STOP : 0;
}
| static int event_hash_fn | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 292 of file res_calendar.c.
References ast_str_hash(), evententry::event, and ast_calendar_event::uid.
Referenced by ast_calendar_event_container_alloc(), and build_calendar().
{
const struct ast_calendar_event *event = obj;
return ast_str_hash(event->uid);
}
| static void event_notification_destroy | ( | void * | data | ) | [static] |
Definition at line 666 of file res_calendar.c.
References ast_calendar_unref_event(), and evententry::event.
{
struct ast_calendar_event *event = data;
event = ast_calendar_unref_event(event);
}
| static void * event_notification_duplicate | ( | void * | data | ) | [static] |
Definition at line 674 of file res_calendar.c.
References ao2_ref, and evententry::event.
{
struct ast_calendar_event *event = data;
if (!event) {
return NULL;
}
ao2_ref(event, +1);
return event;
}
| static void eventlist_destroy | ( | void * | data | ) | [static] |
| static void eventlist_destructor | ( | void * | obj | ) | [static] |
Definition at line 341 of file res_calendar.c.
References ao2_ref, ast_free, AST_LIST_REMOVE_HEAD, evententry::event, events, and evententry::list.
Referenced by calendar_query_exec().
{
struct eventlist *events = obj;
struct evententry *entry;
while ((entry = AST_LIST_REMOVE_HEAD(events, list))) {
ao2_ref(entry->event, -1);
ast_free(entry);
}
}
| static void * eventlist_duplicate | ( | void * | data | ) | [static] |
| static struct ast_calendar* find_calendar | ( | const char * | name | ) | [static, read] |
Definition at line 284 of file res_calendar.c.
References ao2_find, name, ast_calendar::name, and OBJ_POINTER.
Referenced by build_calendar(), calendar_busy_exec(), calendar_query_exec(), calendar_write_exec(), calendarstate(), and handle_show_calendar().
{
struct ast_calendar tmp = {
.name = name,
};
return ao2_find(calendars, &tmp, OBJ_POINTER);
}
| static struct ast_calendar_event* find_event | ( | struct ao2_container * | events, |
| const char * | uid | ||
| ) | [static, read] |
Definition at line 304 of file res_calendar.c.
References ao2_find, OBJ_POINTER, and ast_calendar_event::uid.
Referenced by merge_events_cb().
{
struct ast_calendar_event tmp = {
.uid = uid,
};
return ao2_find(events, &tmp, OBJ_POINTER);
}
| static char* generate_random_string | ( | char * | buf, |
| size_t | size | ||
| ) | [static] |
Generate 32 byte random string (stolen from chan_sip.c)
Definition at line 688 of file res_calendar.c.
References ast_random().
Referenced by calendar_query_exec(), and do_notify().
{
long val[4];
int x;
for (x = 0; x < 4; x++) {
val[x] = ast_random();
}
snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
return buf;
}
| static char* handle_dump_sched | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1645 of file res_calendar.c.
References ast_sched_dump(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
{
switch(cmd) {
case CLI_INIT:
e->command = "calendar dump sched";
e->usage =
"Usage: calendar dump sched\n"
" Dump the calendar sched context";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_sched_dump(sched);
return CLI_SUCCESS;
}
| static char* handle_show_calendar | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 1565 of file res_calendar.c.
References ast_calendar_event::alarm, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_calendar_unref_event(), ast_cli(), ast_strdup, ast_calendar::autoreminder, ast_calendar_event::categories, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_calendar_event::description, ast_calendar_event::end, epoch_to_string(), evententry::event, ast_calendar::events, ast_cli_args::fd, find_calendar(), FORMAT, FORMAT2, ast_calendar_event::location, ast_cli_args::n, ast_calendar::name, ast_calendar::notify_app, ast_calendar::notify_appdata, ast_calendar::notify_channel, ast_calendar::notify_context, ast_calendar::notify_extension, ast_calendar_event::organizer, ast_cli_args::pos, ast_calendar_event::priority, ast_calendar::refresh, ast_calendar_event::start, ast_calendar_event::summary, ast_calendar::timeframe, ast_calendar_event::uid, unref_calendar(), ast_cli_entry::usage, and ast_cli_args::word.
{
#define FORMAT "%-17.17s : %-20.20s\n"
#define FORMAT2 "%-12.12s: %-40.60s\n"
struct ao2_iterator i;
struct ast_calendar *cal;
struct ast_calendar_event *event;
int which = 0;
char *ret = NULL;
switch(cmd) {
case CLI_INIT:
e->command = "calendar show calendar";
e->usage =
"Usage: calendar show calendar <calendar name>\n"
" Displays information about a calendar\n";
return NULL;
case CLI_GENERATE:
if (a->pos != 3) {
return NULL;
}
i = ao2_iterator_init(calendars, 0);
while ((cal = ao2_iterator_next(&i))) {
if (!strncasecmp(a->word, cal->name, strlen(a->word)) && ++which > a->n) {
ret = ast_strdup(cal->name);
cal = unref_calendar(cal);
break;
}
cal = unref_calendar(cal);
}
ao2_iterator_destroy(&i);
return ret;
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
if (!(cal = find_calendar(a->argv[3]))) {
return NULL;
}
ast_cli(a->fd, FORMAT, "Name", cal->name);
ast_cli(a->fd, FORMAT, "Notify channel", cal->notify_channel);
ast_cli(a->fd, FORMAT, "Notify context", cal->notify_context);
ast_cli(a->fd, FORMAT, "Notify extension", cal->notify_extension);
ast_cli(a->fd, FORMAT, "Notify application", cal->notify_app);
ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata);
ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh);
ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe);
ast_cli(a->fd, "%-17.17s : %d\n", "Autoreminder", cal->autoreminder);
ast_cli(a->fd, "%s\n", "Events");
ast_cli(a->fd, "%s\n", "------");
i = ao2_iterator_init(cal->events, 0);
while ((event = ao2_iterator_next(&i))) {
char buf[100];
ast_cli(a->fd, FORMAT2, "Summary", event->summary);
ast_cli(a->fd, FORMAT2, "Description", event->description);
ast_cli(a->fd, FORMAT2, "Organizer", event->organizer);
ast_cli(a->fd, FORMAT2, "Location", event->location);
ast_cli(a->fd, FORMAT2, "Categories", event->categories);
ast_cli(a->fd, "%-12.12s: %d\n", "Priority", event->priority);
ast_cli(a->fd, FORMAT2, "UID", event->uid);
ast_cli(a->fd, FORMAT2, "Start", epoch_to_string(buf, sizeof(buf), event->start));
ast_cli(a->fd, FORMAT2, "End", epoch_to_string(buf, sizeof(buf), event->end));
ast_cli(a->fd, FORMAT2, "Alarm", epoch_to_string(buf, sizeof(buf), event->alarm));
ast_cli(a->fd, "\n");
event = ast_calendar_unref_event(event);
}
ao2_iterator_destroy(&i);
cal = unref_calendar(cal);
return CLI_SUCCESS;
#undef FORMAT
#undef FORMAT2
}
| static char* handle_show_calendars | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command to list available calendars.
Definition at line 1489 of file res_calendar.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), calendar_is_busy(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, ast_calendar::name, ast_calendar::tech, ast_calendar_tech::type, unref_calendar(), and ast_cli_entry::usage.
{
#define FORMAT "%-20.20s %-10.10s %-6.6s\n"
struct ao2_iterator i;
struct ast_calendar *cal;
switch(cmd) {
case CLI_INIT:
e->command = "calendar show calendars";
e->usage =
"Usage: calendar show calendars\n"
" Lists all registered calendars.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, FORMAT, "Calendar", "Type", "Status");
ast_cli(a->fd, FORMAT, "--------", "----", "------");
i = ao2_iterator_init(calendars, 0);
while ((cal = ao2_iterator_next(&i))) {
ast_cli(a->fd, FORMAT, cal->name, cal->tech->type, calendar_is_busy(cal) ? "busy" : "free");
cal = unref_calendar(cal);
}
ao2_iterator_destroy(&i);
return CLI_SUCCESS;
#undef FORMAT
}
| static char* handle_show_calendars_types | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command to list of all calendars types currently loaded on the backend.
Definition at line 1520 of file res_calendar.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_calendar_tech::description, ast_cli_args::fd, FORMAT, evententry::list, ast_calendar_tech::type, and ast_cli_entry::usage.
{
#define FORMAT "%-10.10s %-30.30s\n"
struct ast_calendar_tech *iter;
switch(cmd) {
case CLI_INIT:
e->command = "calendar show types";
e->usage =
"Usage: calendar show types\n"
" Lists all registered calendars types.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, FORMAT, "Type", "Description");
AST_LIST_LOCK(&techs);
AST_LIST_TRAVERSE(&techs, iter, list) {
ast_cli(a->fd, FORMAT, iter->type, iter->description);
}
AST_LIST_UNLOCK(&techs);
return CLI_SUCCESS;
#undef FORMAT
}
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 1026 of file res_calendar.c.
References ast_config_destroy(), ast_config_load2(), ast_log(), ast_rwlock_unlock, ast_rwlock_wrlock, calendar_config, CONFIG_FLAG_FILEUNCHANGED, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, and LOG_ERROR.
Referenced by load_module(), and reload().
{
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
struct ast_config *tmpcfg;
if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
tmpcfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Unable to load config calendar.conf\n");
return -1;
}
if (tmpcfg == CONFIG_STATUS_FILEUNCHANGED) {
return 0;
}
ast_rwlock_wrlock(&config_lock);
if (calendar_config) {
ast_config_destroy(calendar_config);
}
calendar_config = tmpcfg;
ast_rwlock_unlock(&config_lock);
return 0;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 1843 of file res_calendar.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_cond_init, ast_custom_function_register, ast_devstate_prov_add(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_pthread_create_background, ast_sched_context_create(), CALENDAR_BUCKETS, calendar_busy_function, calendar_cli, calendar_cmp_fn(), calendar_event_function, calendar_hash_fn(), calendar_query_function, calendar_query_result_function, calendar_write_function, calendarstate(), do_refresh(), load_config(), and LOG_ERROR.
{
if (!(calendars = ao2_container_alloc(CALENDAR_BUCKETS, calendar_hash_fn, calendar_cmp_fn))) {
ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
return AST_MODULE_LOAD_FAILURE;
}
if (load_config(0)) {
/* We don't have calendar support enabled */
return AST_MODULE_LOAD_DECLINE;
}
ast_mutex_init(&refreshlock);
ast_cond_init(&refresh_condition, NULL);
ast_mutex_init(&reloadlock);
if (!(sched = ast_sched_context_create())) {
ast_log(LOG_ERROR, "Unable to create sched context\n");
return AST_MODULE_LOAD_FAILURE;
}
if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
ast_log(LOG_ERROR, "Unable to start refresh thread--notifications disabled!\n");
}
ast_custom_function_register(&calendar_busy_function);
ast_custom_function_register(&calendar_event_function);
ast_custom_function_register(&calendar_query_function);
ast_custom_function_register(&calendar_query_result_function);
ast_custom_function_register(&calendar_write_function);
ast_cli_register_multiple(calendar_cli, ARRAY_LEN(calendar_cli));
ast_devstate_prov_add("Calendar", calendarstate);
return AST_MODULE_LOAD_SUCCESS;
}
| static int load_tech_calendars | ( | struct ast_calendar_tech * | tech | ) | [static] |
Definition at line 490 of file res_calendar.c.
References ast_calendar_unregister(), ast_category_browse(), ast_log(), ast_rwlock_unlock, ast_rwlock_wrlock, ast_variable_retrieve(), build_calendar(), calendar_config, config_lock, LOG_WARNING, ast_calendar_tech::type, and unref_calendar().
Referenced by ast_calendar_register(), and reload().
{
struct ast_calendar *cal;
const char *cat = NULL;
const char *val;
if (!calendar_config) {
ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
return -1;
}
ast_rwlock_wrlock(&config_lock);
while ((cat = ast_category_browse(calendar_config, cat))) {
if (!strcasecmp(cat, "general")) {
continue;
}
if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) {
continue;
}
/* A serious error occurred loading calendars from this tech and it should be disabled */
if (!(cal = build_calendar(calendar_config, cat, tech))) {
ast_calendar_unregister(tech);
ast_rwlock_unlock(&config_lock);
return -1;
}
cal = unref_calendar(cal);
}
ast_rwlock_unlock(&config_lock);
return 0;
}
| static int match_caltech_cb | ( | void * | user_data, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 547 of file res_calendar.c.
References CMP_MATCH, and ast_calendar::tech.
Referenced by ast_calendar_unregister().
{
struct ast_calendar *cal = user_data;
struct ast_calendar_tech *tech = arg;
if (cal->tech == tech) {
return CMP_MATCH;
}
return 0;
}
| static int merge_events_cb | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
Definition at line 977 of file res_calendar.c.
References ao2_unlink, ast_calendar_unref_event(), CMP_MATCH, copy_event_data(), destroy_event(), find_event(), ast_calendar_event::owner, schedule_calendar_event(), and ast_calendar_event::uid.
Referenced by ast_calendar_merge_events().
{
struct ast_calendar_event *old_event = obj, *new_event;
struct ao2_container *new_events = arg;
/* If we don't find the old_event in new_events, then we can safely delete the old_event */
if (!(new_event = find_event(new_events, old_event->uid))) {
old_event = destroy_event(old_event);
return CMP_MATCH;
}
/* We have events to merge. If any data that will affect a scheduler event has changed,
* then we need to replace the scheduler event */
schedule_calendar_event(old_event->owner, old_event, new_event);
/* Since we don't want to mess with cancelling sched events and adding new ones, just
* copy the internals of the new_event to the old_event */
copy_event_data(old_event, new_event);
/* Now we can go ahead and unlink the new_event from new_events and unref it so that only completely
* new events remain in the container */
ao2_unlink(new_events, new_event);
new_event = ast_calendar_unref_event(new_event);
return 0;
}
| static int null_chan_write | ( | struct ast_channel * | chan, |
| struct ast_frame * | frame | ||
| ) | [static] |
Definition at line 701 of file res_calendar.c.
{
return 0;
}
| static int reload | ( | void | ) | [static] |
Definition at line 1750 of file res_calendar.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, cb_pending_deletion(), cb_rm_pending_deletion(), evententry::list, load_config(), load_tech_calendars(), LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and ast_calendar_tech::type.
{
struct ast_calendar_tech *iter;
ast_mutex_lock(&reloadlock);
/* Mark existing calendars for deletion */
ao2_callback(calendars, OBJ_NODATA | OBJ_MULTIPLE, cb_pending_deletion, NULL);
load_config(1);
AST_LIST_LOCK(&techs);
AST_LIST_TRAVERSE(&techs, iter, list) {
if (load_tech_calendars(iter)) {
ast_log(LOG_WARNING, "Failed to reload %s calendars, module disabled\n", iter->type);
}
}
AST_LIST_UNLOCK(&techs);
/* Delete calendars that no longer show up in the config */
ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, cb_rm_pending_deletion, NULL);
ast_mutex_unlock(&reloadlock);
return 0;
}
| static int schedule_calendar_event | ( | struct ast_calendar * | cal, |
| struct ast_calendar_event * | old_event, | ||
| struct ast_calendar_event * | cmp_event | ||
| ) | [static] |
Definition at line 915 of file res_calendar.c.
References ast_calendar_event::alarm, ao2_lock, ao2_unlock, ast_cond_signal, ast_debug, ast_mutex_lock, ast_mutex_unlock, AST_SCHED_REPLACE, ast_tvnow(), ast_calendar::autoreminder, ast_calendar_event::bs_end_sched, ast_calendar_event::bs_start_sched, calendar_devstate_change(), calendar_event_notify(), ast_calendar_event::end, evententry::event, ast_calendar_event::notify_sched, and ast_calendar_event::start.
Referenced by add_new_event_cb(), and merge_events_cb().
{
struct timeval now = ast_tvnow();
struct ast_calendar_event *event;
time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end;
int changed = 0;
event = cmp_event ? cmp_event : old_event;
ao2_lock(event);
if (!cmp_event || old_event->alarm != event->alarm) {
changed = 1;
if (cal->autoreminder) {
alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000;
} else if (event->alarm) {
alarm_notify_sched = (event->alarm - now.tv_sec) * 1000;
}
/* For now, send the notification if we missed it, but the meeting hasn't happened yet */
if (event->start >= now.tv_sec) {
if (alarm_notify_sched <= 0) {
alarm_notify_sched = 1;
}
ast_mutex_lock(&refreshlock);
AST_SCHED_REPLACE(old_event->notify_sched, sched, alarm_notify_sched, calendar_event_notify, old_event);
ast_mutex_unlock(&refreshlock);
ast_debug(3, "Calendar alarm event notification scheduled to happen in %ld ms\n", (long) alarm_notify_sched);
}
}
if (!cmp_event || old_event->start != event->start) {
changed = 1;
devstate_sched_start = (event->start - now.tv_sec) * 1000;
if (devstate_sched_start < 1) {
devstate_sched_start = 1;
}
ast_mutex_lock(&refreshlock);
AST_SCHED_REPLACE(old_event->bs_start_sched, sched, devstate_sched_start, calendar_devstate_change, old_event);
ast_mutex_unlock(&refreshlock);
ast_debug(3, "Calendar bs_start event notification scheduled to happen in %ld ms\n", (long) devstate_sched_start);
}
if (!cmp_event || old_event->end != event->end) {
changed = 1;
devstate_sched_end = (event->end - now.tv_sec) * 1000;
ast_mutex_lock(&refreshlock);
AST_SCHED_REPLACE(old_event->bs_end_sched, sched, devstate_sched_end, calendar_devstate_change, old_event);
ast_mutex_unlock(&refreshlock);
ast_debug(3, "Calendar bs_end event notification scheduled to happen in %ld ms\n", (long) devstate_sched_end);
}
if (changed) {
ast_cond_signal(&refresh_condition);
}
ao2_unlock(event);
return 0;
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 1807 of file res_calendar.c.
References ao2_callback, ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), ast_cond_signal, ast_config_destroy(), ast_custom_function_unregister(), ast_devstate_prov_del(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_unload_resource(), calendar_busy_function, calendar_cli, calendar_config, calendar_event_function, calendar_query_function, calendar_query_result_function, calendar_write_function, evententry::list, ast_calendar_tech::module, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
{
struct ast_calendar_tech *tech;
ast_devstate_prov_del("calendar");
ast_custom_function_unregister(&calendar_busy_function);
ast_custom_function_unregister(&calendar_event_function);
ast_custom_function_unregister(&calendar_query_function);
ast_custom_function_unregister(&calendar_query_result_function);
ast_custom_function_unregister(&calendar_write_function);
ast_cli_unregister_multiple(calendar_cli, ARRAY_LEN(calendar_cli));
/* Remove all calendars */
ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
ao2_cleanup(calendars);
calendars = NULL;
ast_mutex_lock(&refreshlock);
module_unloading = 1;
ast_cond_signal(&refresh_condition);
ast_mutex_unlock(&refreshlock);
pthread_join(refresh_thread, NULL);
AST_LIST_LOCK(&techs);
AST_LIST_TRAVERSE_SAFE_BEGIN(&techs, tech, list) {
ast_unload_resource(tech->module, 0);
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&techs);
ast_config_destroy(calendar_config);
calendar_config = NULL;
return 0;
}
| static struct ast_calendar* unref_calendar | ( | struct ast_calendar * | cal | ) | [static, read] |
Definition at line 266 of file res_calendar.c.
References ao2_ref.
Referenced by build_calendar(), calendar_busy_exec(), calendar_query_exec(), calendar_write_exec(), calendarstate(), handle_show_calendar(), handle_show_calendars(), and load_tech_calendars().
{
ao2_ref(cal, -1);
return NULL;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Calendar integration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, } [static] |
Definition at line 1884 of file res_calendar.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1884 of file res_calendar.c.
struct ast_custom_function calendar_busy_function [static] |
{
.name = "CALENDAR_BUSY",
.read = calendar_busy_exec,
}
Definition at line 1075 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry calendar_cli[] [static] |
Definition at line 1664 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_config* calendar_config [static] |
Definition at line 246 of file res_calendar.c.
Referenced by ast_calendar_config_acquire(), load_config(), load_tech_calendars(), and unload_module().
struct ast_custom_function calendar_event_function [static] |
{
.name = "CALENDAR_EVENT",
.read = calendar_event_read,
}
Definition at line 1729 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function calendar_query_function [static] |
{
.name = "CALENDAR_QUERY",
.read = calendar_query_exec,
}
Definition at line 1260 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function calendar_query_result_function [static] |
{
.name = "CALENDAR_QUERY_RESULT",
.read = calendar_query_result_exec,
}
Definition at line 1371 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function calendar_write_function [static] |
{
.name = "CALENDAR_WRITE",
.write = calendar_write_exec,
}
Definition at line 1483 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ao2_container* calendars [static] |
Definition at line 213 of file res_calendar.c.
ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } [static] |
Definition at line 247 of file res_calendar.c.
Referenced by ast_calendar_config_release(), load_config(), and load_tech_calendars().
struct ast_datastore_info event_notification_datastore [static] |
{
.type = "EventNotification",
.destroy = event_notification_destroy,
.duplicate = event_notification_duplicate,
}
Definition at line 226 of file res_calendar.c.
struct ast_datastore_info eventlist_datastore_info [static] |
{
.type = "CalendarEventList",
.destroy = eventlist_destroy,
.duplicate = eventlist_duplicate,
}
Definition at line 232 of file res_calendar.c.
int module_unloading [static] |
Definition at line 219 of file res_calendar.c.
struct ast_channel_tech null_tech [static] |
{
.type = "NULL",
.description = "Null channel (should not see this)",
.write = null_chan_write,
}
Definition at line 706 of file res_calendar.c.
Referenced by do_notify().
ast_cond_t refresh_condition [static] |
Definition at line 217 of file res_calendar.c.
pthread_t refresh_thread = AST_PTHREADT_NULL [static] |
Definition at line 215 of file res_calendar.c.
ast_mutex_t refreshlock [static] |
Definition at line 216 of file res_calendar.c.
Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().
ast_mutex_t reloadlock [static] |
Definition at line 218 of file res_calendar.c.
struct ast_sched_context* sched [static] |
Definition at line 214 of file res_calendar.c.