#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 "%-17.17s : %-20.20s\n" |
#define | FORMAT "%-20.20s %-10.10s %-6.6s\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. | |
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. | |
ast_calendar_event * | ast_calendar_event_alloc (struct ast_calendar *cal) |
Allocate an astobj2 ast_calendar_event object. | |
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. | |
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 int | load_config (void *data) |
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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 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 sched_context * | sched |
Support writing attendees
Definition in file res_calendar.c.
#define CALENDAR_BUCKETS 19 |
Definition at line 199 of file res_calendar.c.
Referenced by ast_calendar_event_container_alloc(), build_calendar(), and load_module().
#define FORMAT "%-17.17s : %-20.20s\n" |
#define FORMAT "%-20.20s %-10.10s %-6.6s\n" |
#define FORMAT2 "%-12.12s: %-40.60s\n" |
static void __reg_module | ( | void | ) | [static] |
Definition at line 1760 of file res_calendar.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1760 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 1016 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, events, evententry::list, LOG_ERROR, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.
Referenced by calendar_query_exec().
01017 { 01018 struct evententry *entry, *iter; 01019 int event_startdiff = abs(start - event->start); 01020 int event_enddiff = abs(end - event->end); 01021 int i = 0; 01022 01023 if (!(entry = ast_calloc(1, sizeof(*entry)))) { 01024 ast_log(LOG_ERROR, "Unable to allocate memory for event list\n"); 01025 return -1; 01026 } 01027 01028 entry->event = event; 01029 ao2_ref(event, +1); 01030 01031 if (start == end) { 01032 AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) { 01033 int startdiff = abs(iter->event->start - start); 01034 01035 ast_debug(10, "Comparing %s with startdiff %d to %s with startdiff %d\n", event->summary, event_startdiff, iter->event->summary, startdiff); 01036 ++i; 01037 if (startdiff > event_startdiff) { 01038 AST_LIST_INSERT_BEFORE_CURRENT(entry, list); 01039 return i; 01040 } 01041 if (startdiff == event_startdiff) { 01042 int enddiff = abs(iter->event->end - end); 01043 01044 if (enddiff > event_enddiff) { 01045 AST_LIST_INSERT_BEFORE_CURRENT(entry, list); 01046 return i; 01047 } 01048 if (event_startdiff == enddiff) { 01049 if (strcmp(event->uid, iter->event->uid) < 0) { 01050 AST_LIST_INSERT_BEFORE_CURRENT(entry, list); 01051 return i; 01052 } 01053 } 01054 } 01055 } 01056 AST_LIST_TRAVERSE_SAFE_END; 01057 01058 AST_LIST_INSERT_TAIL(events, entry, list); 01059 01060 return i; 01061 } 01062 01063 AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) { 01064 ++i; 01065 if (iter->event->start > event->start) { 01066 AST_LIST_INSERT_BEFORE_CURRENT(entry, list); 01067 return i; 01068 } 01069 01070 if (iter->event->start == event->start) { 01071 if ((iter->event->end - iter->event->start) == (event->end - event->start)) { 01072 if (strcmp(event->uid, iter->event->uid) < 0) { 01073 AST_LIST_INSERT_BEFORE_CURRENT(entry, list); 01074 return i; 01075 } 01076 } 01077 if ((iter->event->end - iter->event->start) < (event->end - event->start)) { 01078 AST_LIST_INSERT_BEFORE_CURRENT(entry, list); 01079 return i; 01080 } 01081 } 01082 } 01083 AST_LIST_TRAVERSE_SAFE_END; 01084 01085 AST_LIST_INSERT_TAIL(events, entry, list); 01086 01087 return i; 01088 }
static int add_new_event_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 941 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().
00942 { 00943 struct ast_calendar_event *new_event = obj; 00944 struct ao2_container *events = arg; 00945 00946 ao2_link(events, new_event); 00947 schedule_calendar_event(new_event->owner, new_event, NULL); 00948 return CMP_MATCH; 00949 }
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 589 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().
00590 { 00591 ast_debug(3, "Clearing all events for calendar %s\n", cal->name); 00592 00593 ao2_callback(cal->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, clear_events_cb, NULL); 00594 }
struct ast_config* ast_calendar_config_acquire | ( | void | ) |
Grab and lock pointer to the calendar config (read only).
Definition at line 236 of file res_calendar.c.
References ast_rwlock_rdlock, and ast_rwlock_unlock.
Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().
00237 { 00238 ast_rwlock_rdlock(&config_lock); 00239 00240 if (!calendar_config) { 00241 ast_rwlock_unlock(&config_lock); 00242 return NULL; 00243 } 00244 00245 return calendar_config; 00246 }
void ast_calendar_config_release | ( | void | ) |
Release the calendar config.
Definition at line 248 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().
00249 { 00250 ast_rwlock_unlock(&config_lock); 00251 }
struct ast_calendar_event* ast_calendar_event_alloc | ( | struct ast_calendar * | cal | ) |
Allocate an astobj2 ast_calendar_event object.
cal | calendar to allocate an event for |
Definition at line 596 of file res_calendar.c.
References ao2_alloc, ast_calendar_unref_event(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, and calendar_event_destructor().
Referenced by caldav_add_event(), calendar_write_exec(), icalendar_add_event(), parse_tag(), and startelm().
00597 { 00598 struct ast_calendar_event *event; 00599 if (!(event = ao2_alloc(sizeof(*event), calendar_event_destructor))) { 00600 return NULL; 00601 } 00602 00603 if (ast_string_field_init(event, 32)) { 00604 event = ast_calendar_unref_event(event); 00605 return NULL; 00606 } 00607 00608 event->owner = cal; 00609 event->notify_sched = -1; 00610 event->bs_start_sched = -1; 00611 event->bs_end_sched = -1; 00612 00613 AST_LIST_HEAD_INIT_NOLOCK(&event->attendees); 00614 00615 return event; 00616 }
struct ao2_container* ast_calendar_event_container_alloc | ( | void | ) |
Allocate an astobj2 container for ast_calendar_event objects.
Definition at line 618 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().
00619 { 00620 return ao2_container_alloc(CALENDAR_BUCKETS, event_hash_fn, event_cmp_fn); 00621 }
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 951 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().
00952 { 00953 /* Loop through all events attached to the calendar. If there is a matching new event 00954 * merge its data over and handle any schedule changes that need to be made. Then remove 00955 * the new_event from new_events so that we are left with only new_events that we can add later. */ 00956 ao2_callback(cal->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, merge_events_cb, new_events); 00957 00958 /* Now, we should only have completely new events in new_events. Loop through and add them */ 00959 ao2_callback(new_events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, add_new_event_cb, cal->events); 00960 }
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 485 of file res_calendar.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verb, ast_calendar_tech::description, ast_calendar_tech::list, load_tech_calendars(), LOG_WARNING, and ast_calendar_tech::type.
Referenced by load_module().
00486 { 00487 struct ast_calendar_tech *iter; 00488 00489 AST_LIST_LOCK(&techs); 00490 AST_LIST_TRAVERSE(&techs, iter, list) { 00491 if(!strcasecmp(tech->type, iter->type)) { 00492 ast_log(LOG_WARNING, "Already have a handler for calendar type '%s'\n", tech->type); 00493 AST_LIST_UNLOCK(&techs); 00494 return -1; 00495 } 00496 } 00497 AST_LIST_INSERT_HEAD(&techs, tech, list); 00498 AST_LIST_UNLOCK(&techs); 00499 00500 ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description); 00501 00502 return load_tech_calendars(tech); 00503 }
struct ast_calendar_event* ast_calendar_unref_event | ( | struct ast_calendar_event * | event | ) |
Unreference an ast_calendar_event.
event | event to unref |
Definition at line 299 of file res_calendar.c.
References ao2_ref, and evententry::event.
Referenced by ast_calendar_event_alloc(), caldav_add_event(), calendar_devstate_change(), calendar_query_exec(), do_notify(), endelm(), event_notification_destroy(), handle_show_calendar(), icalendar_add_event(), merge_events_cb(), and parse_tag().
00300 { 00301 ao2_ref(event, -1); 00302 return NULL; 00303 }
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 517 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_verb, ast_calendar_tech::list, match_caltech_cb(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and ast_calendar_tech::type.
Referenced by load_tech_calendars(), and unload_module().
00518 { 00519 struct ast_calendar_tech *iter; 00520 00521 AST_LIST_LOCK(&techs); 00522 AST_LIST_TRAVERSE_SAFE_BEGIN(&techs, iter, list) { 00523 if (iter != tech) { 00524 continue; 00525 } 00526 00527 ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, match_caltech_cb, tech); 00528 00529 AST_LIST_REMOVE_CURRENT(list); 00530 ast_verb(2, "Unregistered calendar type '%s'\n", tech->type); 00531 break; 00532 } 00533 AST_LIST_TRAVERSE_SAFE_END; 00534 AST_LIST_UNLOCK(&techs); 00535 00536 }
static struct ast_calendar* build_calendar | ( | struct ast_config * | cfg, | |
const char * | cat, | |||
const struct ast_calendar_tech * | tech | |||
) | [static] |
Definition at line 373 of file res_calendar.c.
References ao2_alloc, ao2_container_alloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_variable_browse(), ast_calendar::autoreminder, CALENDAR_BUCKETS, calendar_destructor(), event_cmp_fn(), event_hash_fn(), find_calendar(), LOG_ERROR, ast_variable::name, name, ast_variable::next, ast_calendar::notify_waittime, ast_calendar::pending_deletion, ast_calendar::refresh, ast_calendar::tech, ast_calendar::timeframe, unref_calendar(), and ast_variable::value.
Referenced by load_tech_calendars().
00374 { 00375 struct ast_calendar *cal; 00376 struct ast_variable *v; 00377 int new_calendar = 0; 00378 00379 if (!(cal = find_calendar(cat))) { 00380 new_calendar = 1; 00381 if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) { 00382 ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n"); 00383 return NULL; 00384 } 00385 00386 if (!(cal->events = ao2_container_alloc(CALENDAR_BUCKETS, event_hash_fn, event_cmp_fn))) { 00387 ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat); 00388 cal = unref_calendar(cal); 00389 return NULL; 00390 } 00391 00392 if (ast_string_field_init(cal, 32)) { 00393 ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat); 00394 cal = unref_calendar(cal); 00395 return NULL; 00396 } 00397 } else { 00398 cal->pending_deletion = 0; 00399 } 00400 00401 ast_string_field_set(cal, name, cat); 00402 cal->tech = tech; 00403 00404 cal->refresh = 3600; 00405 cal->timeframe = 60; 00406 cal->notify_waittime = 30000; 00407 00408 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00409 if (!strcasecmp(v->name, "autoreminder")) { 00410 cal->autoreminder = atoi(v->value); 00411 } else if (!strcasecmp(v->name, "channel")) { 00412 ast_string_field_set(cal, notify_channel, v->value); 00413 } else if (!strcasecmp(v->name, "context")) { 00414 ast_string_field_set(cal, notify_context, v->value); 00415 } else if (!strcasecmp(v->name, "extension")) { 00416 ast_string_field_set(cal, notify_extension, v->value); 00417 } else if (!strcasecmp(v->name, "waittime")) { 00418 int i = atoi(v->value); 00419 if (i > 0) { 00420 cal->notify_waittime = 1000 * i; 00421 } 00422 } else if (!strcasecmp(v->name, "app")) { 00423 ast_string_field_set(cal, notify_app, v->value); 00424 } else if (!strcasecmp(v->name, "appdata")) { 00425 ast_string_field_set(cal, notify_appdata, v->value); 00426 } else if (!strcasecmp(v->name, "refresh")) { 00427 cal->refresh = atoi(v->value); 00428 } else if (!strcasecmp(v->name, "timeframe")) { 00429 cal->timeframe = atoi(v->value); 00430 } 00431 } 00432 00433 if (new_calendar) { 00434 cal->thread = AST_PTHREADT_NULL; 00435 ast_cond_init(&cal->unload, NULL); 00436 ao2_link(calendars, cal); 00437 if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) { 00438 /* If we start failing to create threads, go ahead and return NULL 00439 * and the tech module will be unregistered 00440 */ 00441 ao2_unlink(calendars, cal); 00442 cal = unref_calendar(cal); 00443 } 00444 } 00445 00446 return cal; 00447 }
static int calendar_busy_callback | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 335 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().
00336 { 00337 struct ast_calendar_event *event = obj; 00338 int *is_busy = arg; 00339 struct timeval tv = ast_tvnow(); 00340 00341 if (tv.tv_sec >= event->start && tv.tv_sec <= event->end && event->busy_state > AST_CALENDAR_BS_FREE) { 00342 *is_busy = 1; 00343 return CMP_STOP; 00344 } 00345 00346 return 0; 00347 }
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 990 of file res_calendar.c.
References ast_log(), ast_strlen_zero(), calendar_is_busy(), find_calendar(), and LOG_WARNING.
00991 { 00992 struct ast_calendar *cal; 00993 00994 if (ast_strlen_zero(data)) { 00995 ast_log(LOG_WARNING, "CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n"); 00996 return -1; 00997 } 00998 00999 cal = find_calendar(data); 01000 01001 if (!cal) { 01002 ast_log(LOG_WARNING, "Could not find calendar '%s'\n", data); 01003 return -1; 01004 } 01005 01006 strcpy(buf, calendar_is_busy(cal) ? "1" : "0"); 01007 01008 return 0; 01009 }
static int calendar_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 265 of file res_calendar.c.
References CMP_MATCH, CMP_STOP, and ast_calendar::name.
Referenced by load_module().
00266 { 00267 const struct ast_calendar *one = obj, *two = arg; 00268 return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP: 0; 00269 }
static void calendar_destructor | ( | void * | obj | ) | [static] |
Definition at line 305 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_calendar::events, ast_calendar::name, ast_calendar::tech, ast_calendar::tech_pvt, ast_calendar::thread, ast_calendar::unload, ast_calendar::unloading, and ast_calendar_tech::unref_calendar.
Referenced by build_calendar().
00306 { 00307 struct ast_calendar *cal = obj; 00308 00309 ast_debug(3, "Destroying calendar %s\n", cal->name); 00310 00311 ao2_lock(cal); 00312 cal->unloading = 1; 00313 ast_cond_signal(&cal->unload); 00314 pthread_join(cal->thread, NULL); 00315 if (cal->tech_pvt) { 00316 cal->tech_pvt = cal->tech->unref_calendar(cal->tech_pvt); 00317 } 00318 ast_calendar_clear_events(cal); 00319 ast_string_field_free_memory(cal); 00320 ao2_ref(cal->events, -1); 00321 ao2_unlock(cal); 00322 }
static int calendar_devstate_change | ( | const void * | data | ) | [static] |
Definition at line 790 of file res_calendar.c.
References ao2_ref, ast_calendar_unref_event(), AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, ast_devstate_changed(), ast_log(), ast_tvnow(), ast_calendar_event::bs_end_sched, ast_calendar_event::bs_start_sched, calendar_is_busy(), ast_calendar_event::end, LOG_WARNING, ast_calendar::name, and ast_calendar_event::owner.
Referenced by schedule_calendar_event().
00791 { 00792 struct ast_calendar_event *event = (struct ast_calendar_event *)data; 00793 struct timeval now = ast_tvnow(); 00794 int is_end_event; 00795 00796 if (!event) { 00797 ast_log(LOG_WARNING, "Event was NULL!\n"); 00798 return 0; 00799 } 00800 00801 ao2_ref(event, +1); 00802 00803 is_end_event = event->end <= now.tv_sec; 00804 00805 if (is_end_event) { 00806 event->bs_end_sched = -1; 00807 } else { 00808 event->bs_start_sched = -1; 00809 } 00810 00811 /* We can have overlapping events, so ignore the event->busy_state and check busy state 00812 * based on all events in the calendar */ 00813 if (!calendar_is_busy(event->owner)) { 00814 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name); 00815 } else { 00816 ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name); 00817 } 00818 00819 event = ast_calendar_unref_event(event); 00820 00821 return 0; 00822 }
static void calendar_event_destructor | ( | void * | obj | ) | [static] |
Definition at line 538 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, ast_calendar::name, ast_calendar_attendee::next, and ast_calendar_event::owner.
Referenced by ast_calendar_event_alloc().
00539 { 00540 struct ast_calendar_event *event = obj; 00541 struct ast_calendar_attendee *attendee; 00542 00543 ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name); 00544 ast_string_field_free_memory(event); 00545 while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) { 00546 if (attendee->data) { 00547 ast_free(attendee->data); 00548 } 00549 ast_free(attendee); 00550 } 00551 }
static int calendar_event_notify | ( | const void * | data | ) | [static] |
Definition at line 766 of file res_calendar.c.
References ao2_ref, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, do_notify(), LOG_ERROR, ast_calendar_event::notify_sched, and ast_calendar_event::owner.
Referenced by schedule_calendar_event().
00767 { 00768 struct ast_calendar_event *event = (void *)data; 00769 int res = -1; 00770 pthread_t notify_thread = AST_PTHREADT_NULL; 00771 00772 if (!(event && event->owner)) { 00773 ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n"); 00774 return res; 00775 } 00776 00777 ao2_ref(event, +1); 00778 event->notify_sched = -1; 00779 00780 if (ast_pthread_create_background(¬ify_thread, NULL, do_notify, event) < 0) { 00781 ast_log(LOG_ERROR, "Could not create notification thread\n"); 00782 return res; 00783 } 00784 00785 res = 0; 00786 00787 return res; 00788 }
static int calendar_event_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1567 of file res_calendar.c.
References ast_channel_datastore_find(), ast_channel_lock, 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, event_notification_datastore, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_channel::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.
01568 { 01569 struct ast_datastore *datastore; 01570 struct ast_calendar_event *event; 01571 01572 if (ast_strlen_zero(data)) { 01573 ast_log(LOG_WARNING, "%s requires an argument\n", cmd); 01574 return -1; 01575 } 01576 01577 ast_channel_lock(chan); 01578 if (!(datastore = ast_channel_datastore_find(chan, &event_notification_datastore, NULL))) { 01579 ast_log(LOG_WARNING, "There is no event notification datastore on '%s'!\n", chan->name); 01580 ast_channel_unlock(chan); 01581 return -1; 01582 } 01583 ast_channel_unlock(chan); 01584 01585 if (!(event = datastore->data)) { 01586 ast_log(LOG_WARNING, "The datastore contains no data!\n"); 01587 return -1; 01588 } 01589 01590 if (!strcasecmp(data, "summary")) { 01591 ast_copy_string(buf, event->summary, len); 01592 } else if (!strcasecmp(data, "description")) { 01593 ast_copy_string(buf, event->description, len); 01594 } else if (!strcasecmp(data, "organizer")) { 01595 ast_copy_string(buf, event->organizer, len); 01596 } else if (!strcasecmp(data, "location")) { 01597 ast_copy_string(buf, event->location, len); 01598 } else if (!strcasecmp(data, "categories")) { 01599 ast_copy_string(buf, event->categories, len); 01600 } else if (!strcasecmp(data, "priority")) { 01601 snprintf(buf, len, "%d", event->priority); 01602 } else if (!strcasecmp(data, "calendar")) { 01603 ast_copy_string(buf, event->owner->name, len); 01604 } else if (!strcasecmp(data, "uid")) { 01605 ast_copy_string(buf, event->uid, len); 01606 } else if (!strcasecmp(data, "start")) { 01607 snprintf(buf, len, "%ld", (long)event->start); 01608 } else if (!strcasecmp(data, "end")) { 01609 snprintf(buf, len, "%ld", (long)event->end); 01610 } else if (!strcasecmp(data, "busystate")) { 01611 snprintf(buf, len, "%d", event->busy_state); 01612 } else if (!strcasecmp(data, "attendees")) { 01613 calendar_join_attendees(event, buf, len); 01614 } 01615 01616 01617 return 0; 01618 }
static int calendar_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 259 of file res_calendar.c.
References ast_str_case_hash(), and ast_calendar::name.
Referenced by load_module().
00260 { 00261 const struct ast_calendar *cal = obj; 00262 return ast_str_case_hash(cal->name); 00263 }
static int calendar_is_busy | ( | struct ast_calendar * | cal | ) | [static] |
Definition at line 349 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().
00350 { 00351 int is_busy = 0; 00352 00353 ao2_callback(cal->events, OBJ_NODATA, calendar_busy_callback, &is_busy); 00354 00355 return is_busy; 00356 }
static void calendar_join_attendees | ( | struct ast_calendar_event * | event, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1196 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 ast_calendar_attendee::next.
Referenced by calendar_event_read(), and calendar_query_result_exec().
01197 { 01198 struct ast_str *tmp; 01199 struct ast_calendar_attendee *attendee; 01200 01201 if (!(tmp = ast_str_create(32))) { 01202 ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n"); 01203 return; 01204 } 01205 01206 AST_LIST_TRAVERSE(&event->attendees, attendee, next) { 01207 ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data); 01208 } 01209 01210 ast_copy_string(buf, ast_str_buffer(tmp), len); 01211 ast_free(tmp); 01212 }
static int calendar_query_exec | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1110 of file res_calendar.c.
References add_event_to_list(), ao2_alloc, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, 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, eventlist_datastore_info, eventlist_destructor(), ast_calendar::events, events, find_calendar(), generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_calendar_event::start, ast_calendar_event::summary, and unref_calendar().
01111 { 01112 struct ast_calendar *cal; 01113 struct ao2_iterator i; 01114 struct ast_calendar_event *event; 01115 struct eventlist *events; 01116 time_t start = INT_MIN, end = INT_MAX; 01117 struct ast_datastore *eventlist_datastore; 01118 AST_DECLARE_APP_ARGS(args, 01119 AST_APP_ARG(calendar); 01120 AST_APP_ARG(start); 01121 AST_APP_ARG(end); 01122 ); 01123 01124 if (!chan) { 01125 ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd); 01126 return -1; 01127 } 01128 01129 AST_STANDARD_APP_ARGS(args, data); 01130 01131 if (ast_strlen_zero(args.calendar)) { 01132 ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd); 01133 return -1; 01134 } 01135 01136 if (!(cal = find_calendar(args.calendar))) { 01137 ast_log(LOG_WARNING, "Unknown calendar '%s'\n", args.calendar); 01138 return -1; 01139 } 01140 01141 if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) { 01142 ast_log(LOG_ERROR, "Unable to allocate memory for event list\n"); 01143 cal = unref_calendar(cal); 01144 return -1; 01145 } 01146 01147 if (!ast_strlen_zero(args.start)) { 01148 start = atoi(args.start); 01149 } 01150 01151 if (!ast_strlen_zero(args.end)) { 01152 end = atoi(args.end); 01153 } 01154 01155 i = ao2_iterator_init(cal->events, 0); 01156 while ((event = ao2_iterator_next(&i))) { 01157 if (!(start > event->end || end < event->start)) { 01158 ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end); 01159 if (add_event_to_list(events, event, start, end) < 0) { 01160 event = ast_calendar_unref_event(event); 01161 ao2_iterator_destroy(&i); 01162 return -1; 01163 } 01164 } 01165 01166 event = ast_calendar_unref_event(event); 01167 } 01168 ao2_iterator_destroy(&i); 01169 01170 ast_channel_lock(chan); 01171 do { 01172 generate_random_string(buf, len); 01173 } while (ast_channel_datastore_find(chan, &eventlist_datastore_info, buf)); 01174 ast_channel_unlock(chan); 01175 01176 if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) { 01177 ast_log(LOG_ERROR, "Could not allocate datastore!\n"); 01178 return -1; 01179 } 01180 01181 eventlist_datastore->inheritance = DATASTORE_INHERIT_FOREVER; 01182 eventlist_datastore->data = events; 01183 01184 ast_channel_lock(chan); 01185 ast_channel_datastore_add(chan, eventlist_datastore); 01186 ast_channel_unlock(chan); 01187 01188 return 0; 01189 }
static int calendar_query_result_exec | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1214 of file res_calendar.c.
References args, AST_APP_ARG, ast_channel_datastore_find(), ast_channel_lock, 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, eventlist_datastore_info, events, evententry::list, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_channel::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.
01215 { 01216 struct ast_datastore *datastore; 01217 struct eventlist *events; 01218 struct evententry *entry; 01219 int row = 1; 01220 size_t listlen = 0; 01221 AST_DECLARE_APP_ARGS(args, 01222 AST_APP_ARG(id); 01223 AST_APP_ARG(field); 01224 AST_APP_ARG(row); 01225 ); 01226 01227 if (!chan) { 01228 ast_log(LOG_WARNING, "%s requires a channel\n", cmd); 01229 return -1; 01230 } 01231 01232 AST_STANDARD_APP_ARGS(args, data); 01233 01234 if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) { 01235 ast_log(LOG_WARNING, "%s requires an id and a field", cmd); 01236 return -1; 01237 } 01238 01239 ast_channel_lock(chan); 01240 if (!(datastore = ast_channel_datastore_find(chan, &eventlist_datastore_info, args.id))) { 01241 ast_log(LOG_WARNING, "There is no event notification datastore with id '%s' on '%s'!\n", args.id, chan->name); 01242 ast_channel_unlock(chan); 01243 return -1; 01244 } 01245 ast_channel_unlock(chan); 01246 01247 if (!(events = datastore->data)) { 01248 ast_log(LOG_WARNING, "The datastore contains no data!\n"); 01249 return -1; 01250 } 01251 01252 if (!ast_strlen_zero(args.row)) { 01253 row = atoi(args.row); 01254 } 01255 01256 AST_LIST_TRAVERSE(events, entry, list) { 01257 listlen++; 01258 } 01259 01260 if (!strcasecmp(args.field, "getnum")) { 01261 snprintf(buf, len, "%zu", listlen); 01262 return 0; 01263 } 01264 01265 AST_LIST_TRAVERSE(events, entry, list) { 01266 if (--row) { 01267 continue; 01268 } 01269 if (!strcasecmp(args.field, "summary")) { 01270 ast_copy_string(buf, entry->event->summary, len); 01271 } else if (!strcasecmp(args.field, "description")) { 01272 ast_copy_string(buf, entry->event->description, len); 01273 } else if (!strcasecmp(args.field, "organizer")) { 01274 ast_copy_string(buf, entry->event->organizer, len); 01275 } else if (!strcasecmp(args.field, "location")) { 01276 ast_copy_string(buf, entry->event->location, len); 01277 } else if (!strcasecmp(args.field, "categories")) { 01278 ast_copy_string(buf, entry->event->categories, len); 01279 } else if (!strcasecmp(args.field, "priority")) { 01280 snprintf(buf, len, "%d", entry->event->priority); 01281 } else if (!strcasecmp(args.field, "calendar")) { 01282 ast_copy_string(buf, entry->event->owner->name, len); 01283 } else if (!strcasecmp(args.field, "uid")) { 01284 ast_copy_string(buf, entry->event->uid, len); 01285 } else if (!strcasecmp(args.field, "start")) { 01286 snprintf(buf, len, "%ld", (long) entry->event->start); 01287 } else if (!strcasecmp(args.field, "end")) { 01288 snprintf(buf, len, "%ld", (long) entry->event->end); 01289 } else if (!strcasecmp(args.field, "busystate")) { 01290 snprintf(buf, len, "%d", entry->event->busy_state); 01291 } else if (!strcasecmp(args.field, "attendees")) { 01292 calendar_join_attendees(entry->event, buf, len); 01293 } else { 01294 ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field); 01295 } 01296 break; 01297 } 01298 01299 return 0; 01300 }
static int calendar_write_exec | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 1307 of file res_calendar.c.
References AST_APP_ARG, ast_calendar_event_alloc(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), find_calendar(), LOG_ERROR, LOG_WARNING, ast_calendar::name, ast_calendar_event::owner, ast_calendar::tech, and ast_calendar_tech::write_event.
01308 { 01309 int i, j, ret = -1; 01310 char *val_dup = NULL; 01311 struct ast_calendar *cal = NULL; 01312 struct ast_calendar_event *event = NULL; 01313 struct timeval tv = ast_tvnow(); 01314 AST_DECLARE_APP_ARGS(fields, 01315 AST_APP_ARG(field)[10]; 01316 ); 01317 AST_DECLARE_APP_ARGS(values, 01318 AST_APP_ARG(value)[10]; 01319 ); 01320 01321 if (!(val_dup = ast_strdup(value))) { 01322 ast_log(LOG_ERROR, "Could not allocate memory for values\n"); 01323 return -1; 01324 } 01325 01326 AST_STANDARD_APP_ARGS(fields, data); 01327 AST_STANDARD_APP_ARGS(values, val_dup); 01328 01329 /* XXX Eventually we will support unnamed calendars, so if we don't find one, we parse 01330 * for a calendar type and create it */ 01331 if (!(cal = find_calendar(fields.field[0]))) { 01332 ast_log(LOG_WARNING, "Couldn't find calendar '%s'\n", fields.field[0]); 01333 goto write_cleanup; 01334 } 01335 01336 if (!(cal->tech->write_event)) { 01337 ast_log(LOG_WARNING, "Calendar '%s' has no write function!\n", cal->name); 01338 goto write_cleanup; 01339 } 01340 01341 if (!(event = ast_calendar_event_alloc(cal))) { 01342 goto write_cleanup; 01343 } 01344 01345 if (ast_strlen_zero(fields.field[0])) { 01346 ast_log(LOG_WARNING, "CALENDAR_WRITE requires a calendar name!\n"); 01347 goto write_cleanup; 01348 } 01349 01350 if (fields.argc - 1 != values.argc) { 01351 ast_log(LOG_WARNING, "CALENDAR_WRITE should have the same number of fields (%d) and values (%d)!\n", fields.argc - 1, values.argc); 01352 goto write_cleanup; 01353 } 01354 01355 event->owner = cal; 01356 01357 for (i = 1, j = 0; i < fields.argc; i++, j++) { 01358 if (!strcasecmp(fields.field[i], "summary")) { 01359 ast_string_field_set(event, summary, values.value[j]); 01360 } else if (!strcasecmp(fields.field[i], "description")) { 01361 ast_string_field_set(event, description, values.value[j]); 01362 } else if (!strcasecmp(fields.field[i], "organizer")) { 01363 ast_string_field_set(event, organizer, values.value[j]); 01364 } else if (!strcasecmp(fields.field[i], "location")) { 01365 ast_string_field_set(event, location, values.value[j]); 01366 } else if (!strcasecmp(fields.field[i], "categories")) { 01367 ast_string_field_set(event, categories, values.value[j]); 01368 } else if (!strcasecmp(fields.field[i], "priority")) { 01369 event->priority = atoi(values.value[j]); 01370 } else if (!strcasecmp(fields.field[i], "uid")) { 01371 ast_string_field_set(event, uid, values.value[j]); 01372 } else if (!strcasecmp(fields.field[i], "start")) { 01373 event->start = atoi(values.value[j]); 01374 } else if (!strcasecmp(fields.field[i], "end")) { 01375 event->end = atoi(values.value[j]); 01376 } else if (!strcasecmp(fields.field[i], "busystate")) { 01377 event->busy_state = atoi(values.value[j]); 01378 } else { 01379 ast_log(LOG_WARNING, "Unknown calendar event field '%s'\n", fields.field[i]); 01380 } 01381 } 01382 01383 if (!event->start) { 01384 event->start = tv.tv_sec; 01385 } 01386 01387 if (!event->end) { 01388 event->end = tv.tv_sec; 01389 } 01390 01391 if((ret = cal->tech->write_event(event))) { 01392 ast_log(LOG_WARNING, "Writing event to calendar '%s' failed!\n", cal->name); 01393 } 01394 01395 write_cleanup: 01396 if (cal) { 01397 cal = unref_calendar(cal); 01398 } 01399 if (event) { 01400 event = ast_calendar_unref_event(event); 01401 } 01402 if (val_dup) { 01403 ast_free(val_dup); 01404 } 01405 01406 return ret; 01407 }
static enum ast_device_state calendarstate | ( | const char * | data | ) | [static] |
Definition at line 358 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, and ast_calendar::tech.
Referenced by load_module().
00359 { 00360 struct ast_calendar *cal; 00361 00362 if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) { 00363 return AST_DEVICE_INVALID; 00364 } 00365 00366 if (cal->tech->is_busy) { 00367 return cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE; 00368 } 00369 00370 return calendar_is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE; 00371 }
static int cb_pending_deletion | ( | void * | user_data, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1625 of file res_calendar.c.
References CMP_MATCH, and ast_calendar::pending_deletion.
Referenced by reload().
01626 { 01627 struct ast_calendar *cal = user_data; 01628 01629 cal->pending_deletion = 1; 01630 01631 return CMP_MATCH; 01632 }
static int cb_rm_pending_deletion | ( | void * | user_data, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1634 of file res_calendar.c.
References CMP_MATCH, and ast_calendar::pending_deletion.
Referenced by reload().
01635 { 01636 struct ast_calendar *cal = user_data; 01637 01638 return cal->pending_deletion ? CMP_MATCH : 0; 01639 }
static int clear_events_cb | ( | void * | user_data, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 580 of file res_calendar.c.
References CMP_MATCH, and destroy_event().
Referenced by ast_calendar_clear_events().
00581 { 00582 struct ast_calendar_event *event = user_data; 00583 00584 event = destroy_event(event); 00585 00586 return CMP_MATCH; 00587 }
static void copy_event_data | ( | struct ast_calendar_event * | dst, | |
struct ast_calendar_event * | src | |||
) | [static] |
Definition at line 824 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, ast_calendar_attendee::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().
00825 { 00826 struct ast_calendar_attendee *attendee; 00827 00828 ast_string_field_set(dst, summary, src->summary); 00829 ast_string_field_set(dst, description, src->description); 00830 ast_string_field_set(dst, organizer, src->organizer); 00831 ast_string_field_set(dst, location, src->location); 00832 ast_string_field_set(dst, uid, src->uid); 00833 ast_string_field_set(dst, categories, src->categories); 00834 dst->priority = src->priority; 00835 dst->owner = src->owner; 00836 dst->start = src->start; 00837 dst->end = src->end; 00838 dst->alarm = src->alarm; 00839 dst->busy_state = src->busy_state; 00840 00841 /* Delete any existing attendees */ 00842 while ((attendee = AST_LIST_REMOVE_HEAD(&dst->attendees, next))) { 00843 ast_free(attendee); 00844 } 00845 00846 /* Copy over the new attendees */ 00847 while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) { 00848 AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next); 00849 } 00850 }
static struct ast_calendar_event* destroy_event | ( | struct ast_calendar_event * | event | ) | [static] |
Definition at line 555 of file res_calendar.c.
References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, 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, ast_calendar_event::owner, and sched.
Referenced by clear_events_cb(), and merge_events_cb().
00556 { 00557 if (event->notify_sched > -1 && ast_sched_del(sched, event->notify_sched)) { 00558 ast_debug(3, "Notification running, can't delete sched entry\n"); 00559 } 00560 if (event->bs_start_sched > -1 && ast_sched_del(sched, event->bs_start_sched)) { 00561 ast_debug(3, "Devicestate update (start) running, can't delete sched entry\n"); 00562 } 00563 if (event->bs_end_sched > -1 && ast_sched_del(sched, event->bs_end_sched)) { 00564 ast_debug(3, "Devicestate update (end) running, can't delete sched entry\n"); 00565 } 00566 00567 /* If an event is being deleted and we've fired an event changing the status at the beginning, 00568 * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */ 00569 if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) { 00570 if (!calendar_is_busy(event->owner)) { 00571 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name); 00572 } else { 00573 ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name); 00574 } 00575 } 00576 00577 return NULL; 00578 }
static void* do_notify | ( | void * | data | ) | [static] |
Definition at line 669 of file res_calendar.c.
References ao2_ref, ast_calendar_unref_event(), ast_channel_alloc, ast_channel_datastore_add(), ast_channel_release(), ast_copy_string(), 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_SLINEAR, ast_free, ast_log(), ast_pbx_run(), AST_STATE_DOWN, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_verb, ast_channel::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, event_notification_datastore, ast_channel::exten, generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_calendar::name, ast_channel::nativeformats, 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, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::tech, and ast_channel::writeformat.
Referenced by calendar_event_notify().
00670 { 00671 struct ast_calendar_event *event = data; 00672 struct ast_dial *dial = NULL; 00673 struct ast_str *apptext = NULL; 00674 struct ast_datastore *datastore; 00675 enum ast_dial_result res; 00676 struct ast_channel *chan = NULL; 00677 char *tech, *dest; 00678 char buf[8]; 00679 00680 tech = ast_strdupa(event->owner->notify_channel); 00681 00682 if ((dest = strchr(tech, '/'))) { 00683 *dest = '\0'; 00684 dest++; 00685 } else { 00686 ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech); 00687 goto notify_cleanup; 00688 } 00689 00690 if (!(dial = ast_dial_create())) { 00691 ast_log(LOG_ERROR, "Could not create dial structure\n"); 00692 goto notify_cleanup; 00693 } 00694 00695 if (ast_dial_append(dial, tech, dest) < 0) { 00696 ast_log(LOG_ERROR, "Could not append channel\n"); 00697 goto notify_cleanup; 00698 } 00699 00700 ast_dial_set_global_timeout(dial, event->owner->notify_waittime); 00701 generate_random_string(buf, sizeof(buf)); 00702 00703 if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "Calendar/%s-%s", event->owner->name, buf))) { 00704 ast_log(LOG_ERROR, "Could not allocate notification channel\n"); 00705 goto notify_cleanup; 00706 } 00707 00708 chan->tech = &null_tech; 00709 chan->nativeformats = chan->writeformat = chan->rawwriteformat = 00710 chan->readformat = chan->rawreadformat = AST_FORMAT_SLINEAR; 00711 00712 if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) { 00713 ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n"); 00714 goto notify_cleanup; 00715 } 00716 00717 datastore->data = event; 00718 datastore->inheritance = DATASTORE_INHERIT_FOREVER; 00719 00720 ao2_ref(event, +1); 00721 res = ast_channel_datastore_add(chan, datastore); 00722 00723 if (!(apptext = ast_str_create(32))) { 00724 goto notify_cleanup; 00725 } 00726 00727 if (!ast_strlen_zero(event->owner->notify_app)) { 00728 ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata); 00729 ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, ast_str_buffer(apptext)); 00730 } else { 00731 } 00732 00733 ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name); 00734 res = ast_dial_run(dial, chan, 0); 00735 00736 if (res != AST_DIAL_RESULT_ANSWERED) { 00737 ast_verb(3, "Notification call for %s was not completed\n", event->owner->name); 00738 } else { 00739 struct ast_channel *answered; 00740 00741 answered = ast_dial_answered_steal(dial); 00742 if (ast_strlen_zero(event->owner->notify_app)) { 00743 ast_copy_string(answered->context, event->owner->notify_context, sizeof(answered->context)); 00744 ast_copy_string(answered->exten, event->owner->notify_extension, sizeof(answered->exten)); 00745 answered->priority = 1; 00746 ast_pbx_run(answered); 00747 } 00748 } 00749 00750 notify_cleanup: 00751 if (apptext) { 00752 ast_free(apptext); 00753 } 00754 if (dial) { 00755 ast_dial_destroy(dial); 00756 } 00757 if (chan) { 00758 ast_channel_release(chan); 00759 } 00760 00761 event = ast_calendar_unref_event(event); 00762 00763 return NULL; 00764 }
static void* do_refresh | ( | void * | data | ) | [static] |
Definition at line 1667 of file res_calendar.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_tvnow(), refreshlock, and sched.
01668 { 01669 for (;;) { 01670 struct timeval now = ast_tvnow(); 01671 struct timespec ts = {0,}; 01672 int wait; 01673 01674 ast_mutex_lock(&refreshlock); 01675 01676 if ((wait = ast_sched_wait(sched)) < 0) { 01677 wait = 1000; 01678 } 01679 01680 ts.tv_sec = (now.tv_sec + wait / 1000) + 1; 01681 ast_cond_timedwait(&refresh_condition, &refreshlock, &ts); 01682 01683 ast_mutex_unlock(&refreshlock); 01684 01685 ast_sched_runq(sched); 01686 } 01687 01688 return NULL; 01689 }
static char* epoch_to_string | ( | char * | buf, | |
size_t | buflen, | |||
time_t | epoch | |||
) | [static] |
Definition at line 1445 of file res_calendar.c.
References ast_localtime(), and ast_strftime().
Referenced by handle_show_calendar().
01446 { 01447 struct ast_tm tm; 01448 struct timeval tv = { 01449 .tv_sec = epoch, 01450 }; 01451 01452 if (!epoch) { 01453 *buf = '\0'; 01454 return buf; 01455 } 01456 ast_localtime(&tv, &tm, NULL); 01457 ast_strftime(buf, buflen, "%F %r %z", &tm); 01458 01459 return buf; 01460 }
static int event_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 285 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().
00286 { 00287 const struct ast_calendar_event *one = obj, *two = arg; 00288 return !strcmp(one->uid, two->uid) ? CMP_MATCH | CMP_STOP : 0; 00289 }
static int event_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 279 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().
00280 { 00281 const struct ast_calendar_event *event = obj; 00282 return ast_str_hash(event->uid); 00283 }
static void event_notification_destroy | ( | void * | data | ) | [static] |
Definition at line 623 of file res_calendar.c.
References ast_calendar_unref_event().
00624 { 00625 struct ast_calendar_event *event = data; 00626 00627 event = ast_calendar_unref_event(event); 00628 00629 }
static void * event_notification_duplicate | ( | void * | data | ) | [static] |
Definition at line 631 of file res_calendar.c.
References ao2_ref.
00632 { 00633 struct ast_calendar_event *event = data; 00634 00635 if (!event) { 00636 return NULL; 00637 } 00638 00639 ao2_ref(event, +1); 00640 00641 return event; 00642 }
static void eventlist_destroy | ( | void * | data | ) | [static] |
static void eventlist_destructor | ( | void * | obj | ) | [static] |
Definition at line 324 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().
00325 { 00326 struct eventlist *events = obj; 00327 struct evententry *entry; 00328 00329 while ((entry = AST_LIST_REMOVE_HEAD(events, list))) { 00330 ao2_ref(entry->event, -1); 00331 ast_free(entry); 00332 } 00333 }
static void * eventlist_duplicate | ( | void * | data | ) | [static] |
static struct ast_calendar* find_calendar | ( | const char * | name | ) | [static] |
Definition at line 271 of file res_calendar.c.
References ao2_find, calendars, ast_calendar::name, and OBJ_POINTER.
Referenced by build_calendar(), calendar_busy_exec(), calendar_query_exec(), calendar_write_exec(), calendarstate(), and handle_show_calendar().
00272 { 00273 struct ast_calendar tmp = { 00274 .name = name, 00275 }; 00276 return ao2_find(calendars, &tmp, OBJ_POINTER); 00277 }
static struct ast_calendar_event* find_event | ( | struct ao2_container * | events, | |
const char * | uid | |||
) | [static] |
Definition at line 291 of file res_calendar.c.
References ao2_find, events, OBJ_POINTER, and ast_calendar_event::uid.
Referenced by merge_events_cb().
00292 { 00293 struct ast_calendar_event tmp = { 00294 .uid = uid, 00295 }; 00296 return ao2_find(events, &tmp, OBJ_POINTER); 00297 }
static char* generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string (stolen from chan_sip.c).
Definition at line 645 of file res_calendar.c.
References ast_random().
00646 { 00647 long val[4]; 00648 int x; 00649 00650 for (x = 0; x < 4; x++) { 00651 val[x] = ast_random(); 00652 } 00653 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 00654 00655 return buf; 00656 }
static char* handle_dump_sched | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1542 of file res_calendar.c.
References ast_sched_dump(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, sched, and ast_cli_entry::usage.
01543 { 01544 switch(cmd) { 01545 case CLI_INIT: 01546 e->command = "calendar dump sched"; 01547 e->usage = 01548 "Usage: calendar dump sched\n" 01549 " Dump the calendar sched context"; 01550 return NULL; 01551 01552 case CLI_GENERATE: 01553 return NULL; 01554 } 01555 01556 ast_sched_dump(sched); 01557 01558 return CLI_SUCCESS; 01559 }
static char* handle_show_calendar | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1462 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(), 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.
01463 { 01464 #define FORMAT "%-17.17s : %-20.20s\n" 01465 #define FORMAT2 "%-12.12s: %-40.60s\n" 01466 struct ao2_iterator i; 01467 struct ast_calendar *cal; 01468 struct ast_calendar_event *event; 01469 int which = 0; 01470 char *ret = NULL; 01471 01472 switch(cmd) { 01473 case CLI_INIT: 01474 e->command = "calendar show calendar"; 01475 e->usage = 01476 "Usage: calendar show calendar <calendar name>\n" 01477 " Displays information about a calendar\n"; 01478 return NULL; 01479 01480 case CLI_GENERATE: 01481 if (a->pos != 3) { 01482 return NULL; 01483 } 01484 i = ao2_iterator_init(calendars, 0); 01485 while ((cal = ao2_iterator_next(&i))) { 01486 if (!strncasecmp(a->word, cal->name, strlen(a->word)) && ++which > a->n) { 01487 ret = ast_strdup(cal->name); 01488 cal = unref_calendar(cal); 01489 break; 01490 } 01491 cal = unref_calendar(cal); 01492 } 01493 ao2_iterator_destroy(&i); 01494 return ret; 01495 } 01496 01497 if (a->argc != 4) { 01498 return CLI_SHOWUSAGE; 01499 } 01500 01501 if (!(cal = find_calendar(a->argv[3]))) { 01502 return NULL; 01503 } 01504 01505 ast_cli(a->fd, FORMAT, "Name", cal->name); 01506 ast_cli(a->fd, FORMAT, "Notify channel", cal->notify_channel); 01507 ast_cli(a->fd, FORMAT, "Notify context", cal->notify_context); 01508 ast_cli(a->fd, FORMAT, "Notify extension", cal->notify_extension); 01509 ast_cli(a->fd, FORMAT, "Notify application", cal->notify_app); 01510 ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata); 01511 ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh); 01512 ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe); 01513 ast_cli(a->fd, "%-17.17s : %d\n", "Autoreminder", cal->autoreminder); 01514 ast_cli(a->fd, "%s\n", "Events"); 01515 ast_cli(a->fd, "%s\n", "------"); 01516 01517 i = ao2_iterator_init(cal->events, 0); 01518 while ((event = ao2_iterator_next(&i))) { 01519 char buf[100]; 01520 01521 ast_cli(a->fd, FORMAT2, "Summary", event->summary); 01522 ast_cli(a->fd, FORMAT2, "Description", event->description); 01523 ast_cli(a->fd, FORMAT2, "Organizer", event->organizer); 01524 ast_cli(a->fd, FORMAT2, "Location", event->location); 01525 ast_cli(a->fd, FORMAT2, "Categories", event->categories); 01526 ast_cli(a->fd, "%-12.12s: %d\n", "Priority", event->priority); 01527 ast_cli(a->fd, FORMAT2, "UID", event->uid); 01528 ast_cli(a->fd, FORMAT2, "Start", epoch_to_string(buf, sizeof(buf), event->start)); 01529 ast_cli(a->fd, FORMAT2, "End", epoch_to_string(buf, sizeof(buf), event->end)); 01530 ast_cli(a->fd, FORMAT2, "Alarm", epoch_to_string(buf, sizeof(buf), event->alarm)); 01531 ast_cli(a->fd, "\n"); 01532 01533 event = ast_calendar_unref_event(event); 01534 } 01535 ao2_iterator_destroy(&i); 01536 cal = unref_calendar(cal); 01537 return CLI_SUCCESS; 01538 #undef FORMAT 01539 #undef FORMAT2 01540 }
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 1415 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.
01416 { 01417 #define FORMAT "%-20.20s %-10.10s %-6.6s\n" 01418 struct ao2_iterator i; 01419 struct ast_calendar *cal; 01420 01421 switch(cmd) { 01422 case CLI_INIT: 01423 e->command = "calendar show calendars"; 01424 e->usage = 01425 "Usage: calendar show calendars\n" 01426 " Lists all registered calendars.\n"; 01427 return NULL; 01428 case CLI_GENERATE: 01429 return NULL; 01430 } 01431 01432 ast_cli(a->fd, FORMAT, "Calendar", "Type", "Status"); 01433 ast_cli(a->fd, FORMAT, "--------", "----", "------"); 01434 i = ao2_iterator_init(calendars, 0); 01435 while ((cal = ao2_iterator_next(&i))) { 01436 ast_cli(a->fd, FORMAT, cal->name, cal->tech->type, calendar_is_busy(cal) ? "busy" : "free"); 01437 cal = unref_calendar(cal); 01438 } 01439 ao2_iterator_destroy(&i); 01440 01441 return CLI_SUCCESS; 01442 #undef FORMAT 01443 }
static int load_config | ( | void * | data | ) | [static] |
Definition at line 963 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_flags, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, and LOG_ERROR.
00964 { 00965 struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED }; 00966 struct ast_config *tmpcfg; 00967 00968 if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) || 00969 tmpcfg == CONFIG_STATUS_FILEINVALID) { 00970 ast_log(LOG_ERROR, "Unable to load config calendar.conf\n"); 00971 return -1; 00972 } 00973 00974 if (tmpcfg == CONFIG_STATUS_FILEUNCHANGED) { 00975 return 0; 00976 } 00977 00978 ast_rwlock_wrlock(&config_lock); 00979 if (calendar_config) { 00980 ast_config_destroy(calendar_config); 00981 } 00982 00983 calendar_config = tmpcfg; 00984 ast_rwlock_unlock(&config_lock); 00985 00986 return 0; 00987 }
static int load_module | ( | void | ) | [static] |
Definition at line 1716 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_module_ref(), ast_mutex_init, ast_pthread_create_background, 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(), LOG_ERROR, refreshlock, reloadlock, sched, and sched_context_create().
01717 { 01718 if (!(calendars = ao2_container_alloc(CALENDAR_BUCKETS, calendar_hash_fn, calendar_cmp_fn))) { 01719 ast_log(LOG_ERROR, "Unable to allocate calendars container!\n"); 01720 return AST_MODULE_LOAD_FAILURE; 01721 } 01722 01723 if (load_config(NULL)) { 01724 /* We don't have calendar support enabled */ 01725 return AST_MODULE_LOAD_DECLINE; 01726 } 01727 01728 ast_mutex_init(&refreshlock); 01729 ast_cond_init(&refresh_condition, NULL); 01730 ast_mutex_init(&reloadlock); 01731 01732 if (!(sched = sched_context_create())) { 01733 ast_log(LOG_ERROR, "Unable to create sched context\n"); 01734 return AST_MODULE_LOAD_FAILURE; 01735 } 01736 01737 if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) { 01738 ast_log(LOG_ERROR, "Unable to start refresh thread--notifications disabled!\n"); 01739 } 01740 01741 ast_custom_function_register(&calendar_busy_function); 01742 ast_custom_function_register(&calendar_event_function); 01743 ast_custom_function_register(&calendar_query_function); 01744 ast_custom_function_register(&calendar_query_result_function); 01745 ast_custom_function_register(&calendar_write_function); 01746 ast_cli_register_multiple(calendar_cli, ARRAY_LEN(calendar_cli)); 01747 01748 ast_devstate_prov_add("Calendar", calendarstate); 01749 01750 /* Since other modules depend on this, disable unloading */ 01751 ast_module_ref(ast_module_info->self); 01752 01753 return AST_MODULE_LOAD_SUCCESS; 01754 }
static int load_tech_calendars | ( | struct ast_calendar_tech * | tech | ) | [static] |
Definition at line 449 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, ast_calendar_tech::type, and unref_calendar().
Referenced by ast_calendar_register(), and reload().
00450 { 00451 struct ast_calendar *cal; 00452 const char *cat = NULL; 00453 const char *val; 00454 00455 if (!calendar_config) { 00456 ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type); 00457 return -1; 00458 } 00459 00460 ast_rwlock_wrlock(&config_lock); 00461 while ((cat = ast_category_browse(calendar_config, cat))) { 00462 if (!strcasecmp(cat, "general")) { 00463 continue; 00464 } 00465 00466 if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) { 00467 continue; 00468 } 00469 00470 /* A serious error occurred loading calendars from this tech and it should be disabled */ 00471 if (!(cal = build_calendar(calendar_config, cat, tech))) { 00472 ast_calendar_unregister(tech); 00473 ast_rwlock_unlock(&config_lock); 00474 return -1; 00475 } 00476 00477 cal = unref_calendar(cal); 00478 } 00479 00480 ast_rwlock_unlock(&config_lock); 00481 00482 return 0; 00483 }
static int match_caltech_cb | ( | void * | user_data, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 505 of file res_calendar.c.
References CMP_MATCH, and ast_calendar::tech.
Referenced by ast_calendar_unregister().
00506 { 00507 struct ast_calendar *cal = user_data; 00508 struct ast_calendar_tech *tech = arg; 00509 00510 if (cal->tech == tech) { 00511 return CMP_MATCH; 00512 } 00513 00514 return 0; 00515 }
static int merge_events_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 914 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().
00915 { 00916 struct ast_calendar_event *old_event = obj, *new_event; 00917 struct ao2_container *new_events = arg; 00918 00919 /* If we don't find the old_event in new_events, then we can safely delete the old_event */ 00920 if (!(new_event = find_event(new_events, old_event->uid))) { 00921 old_event = destroy_event(old_event); 00922 return CMP_MATCH; 00923 } 00924 00925 /* We have events to merge. If any data that will affect a scheduler event has changed, 00926 * then we need to replace the scheduler event */ 00927 schedule_calendar_event(old_event->owner, old_event, new_event); 00928 00929 /* Since we don't want to mess with cancelling sched events and adding new ones, just 00930 * copy the internals of the new_event to the old_event */ 00931 copy_event_data(old_event, new_event); 00932 00933 /* Now we can go ahead and unlink the new_event from new_events and unref it so that only completely 00934 * new events remain in the container */ 00935 ao2_unlink(new_events, new_event); 00936 new_event = ast_calendar_unref_event(new_event); 00937 00938 return 0; 00939 }
static int null_chan_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | frame | |||
) | [static] |
static int reload | ( | void | ) | [static] |
Definition at line 1641 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(), ast_calendar_tech::list, load_config(), load_tech_calendars(), LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, reloadlock, and ast_calendar_tech::type.
01642 { 01643 struct ast_calendar_tech *iter; 01644 01645 ast_mutex_lock(&reloadlock); 01646 01647 /* Mark existing calendars for deletion */ 01648 ao2_callback(calendars, OBJ_NODATA | OBJ_MULTIPLE, cb_pending_deletion, NULL); 01649 load_config(NULL); 01650 01651 AST_LIST_LOCK(&techs); 01652 AST_LIST_TRAVERSE(&techs, iter, list) { 01653 if (load_tech_calendars(iter)) { 01654 ast_log(LOG_WARNING, "Failed to reload %s calendars, module disabled\n", iter->type); 01655 } 01656 } 01657 AST_LIST_UNLOCK(&techs); 01658 01659 /* Delete calendars that no longer show up in the config */ 01660 ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, cb_rm_pending_deletion, NULL); 01661 01662 ast_mutex_unlock(&reloadlock); 01663 01664 return 0; 01665 }
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 852 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, ast_calendar_event::notify_sched, refreshlock, sched, and ast_calendar_event::start.
Referenced by add_new_event_cb(), and merge_events_cb().
00853 { 00854 struct timeval now = ast_tvnow(); 00855 struct ast_calendar_event *event; 00856 time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end; 00857 int changed = 0; 00858 00859 event = cmp_event ? cmp_event : old_event; 00860 00861 ao2_lock(event); 00862 if (!cmp_event || old_event->alarm != event->alarm) { 00863 changed = 1; 00864 if (cal->autoreminder) { 00865 alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000; 00866 } else if (event->alarm) { 00867 alarm_notify_sched = (event->alarm - now.tv_sec) * 1000; 00868 } 00869 00870 /* For now, send the notification if we missed it, but the meeting hasn't happened yet */ 00871 if (event->start >= now.tv_sec) { 00872 if (alarm_notify_sched <= 0) { 00873 alarm_notify_sched = 1; 00874 } 00875 ast_mutex_lock(&refreshlock); 00876 AST_SCHED_REPLACE(old_event->notify_sched, sched, alarm_notify_sched, calendar_event_notify, old_event); 00877 ast_mutex_unlock(&refreshlock); 00878 ast_debug(3, "Calendar alarm event notification scheduled to happen in %ld ms\n", (long) alarm_notify_sched); 00879 } 00880 } 00881 00882 if (!cmp_event || old_event->start != event->start) { 00883 changed = 1; 00884 devstate_sched_start = (event->start - now.tv_sec) * 1000; 00885 00886 if (devstate_sched_start < 1) { 00887 devstate_sched_start = 1; 00888 } 00889 00890 ast_mutex_lock(&refreshlock); 00891 AST_SCHED_REPLACE(old_event->bs_start_sched, sched, devstate_sched_start, calendar_devstate_change, old_event); 00892 ast_mutex_unlock(&refreshlock); 00893 ast_debug(3, "Calendar bs_start event notification scheduled to happen in %ld ms\n", (long) devstate_sched_start); 00894 } 00895 00896 if (!cmp_event || old_event->end != event->end) { 00897 changed = 1; 00898 devstate_sched_end = (event->end - now.tv_sec) * 1000; 00899 ast_mutex_lock(&refreshlock); 00900 AST_SCHED_REPLACE(old_event->bs_end_sched, sched, devstate_sched_end, calendar_devstate_change, old_event); 00901 ast_mutex_unlock(&refreshlock); 00902 ast_debug(3, "Calendar bs_end event notification scheduled to happen in %ld ms\n", (long) devstate_sched_end); 00903 } 00904 00905 if (changed) { 00906 ast_cond_signal(&refresh_condition); 00907 } 00908 00909 ao2_unlock(event); 00910 00911 return 0; 00912 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1692 of file res_calendar.c.
References ao2_callback, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_devstate_prov_del(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_resource(), calendar_busy_function, calendar_cli, calendar_event_function, calendar_query_function, calendar_query_result_function, calendar_write_function, ast_calendar_tech::list, ast_calendar_tech::module, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.
01693 { 01694 struct ast_calendar_tech *tech; 01695 01696 ast_devstate_prov_del("calendar"); 01697 ast_custom_function_unregister(&calendar_busy_function); 01698 ast_custom_function_unregister(&calendar_event_function); 01699 ast_custom_function_unregister(&calendar_query_function); 01700 ast_custom_function_unregister(&calendar_query_result_function); 01701 ast_custom_function_unregister(&calendar_write_function); 01702 ast_cli_unregister_multiple(calendar_cli, ARRAY_LEN(calendar_cli)); 01703 01704 /* Remove all calendars */ 01705 ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL); 01706 01707 AST_LIST_LOCK(&techs); 01708 AST_LIST_TRAVERSE(&techs, tech, list) { 01709 ast_unload_resource(tech->module, 0); 01710 } 01711 AST_LIST_UNLOCK(&techs); 01712 01713 return 0; 01714 }
static struct ast_calendar* unref_calendar | ( | struct ast_calendar * | cal | ) | [static] |
Definition at line 253 of file res_calendar.c.
References ao2_ref.
Referenced by build_calendar(), calendar_query_exec(), handle_show_calendar(), handle_show_calendars(), and load_tech_calendars().
00254 { 00255 ao2_ref(cal, -1); 00256 return NULL; 00257 }
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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, } [static] |
Definition at line 1760 of file res_calendar.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1760 of file res_calendar.c.
struct ast_custom_function calendar_busy_function [static] |
Initial value:
{ .name = "CALENDAR_BUSY", .read = calendar_busy_exec, }
Definition at line 1011 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry calendar_cli[] [static] |
Initial value:
{ { .handler = handle_show_calendar , .summary = "Display information about a calendar" ,__VA_ARGS__ }, { .handler = handle_show_calendars , .summary = "Show registered calendars" ,__VA_ARGS__ }, { .handler = handle_dump_sched , .summary = "Dump calendar sched context" ,__VA_ARGS__ }, }
Definition at line 1561 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_config* calendar_config [static] |
Definition at line 233 of file res_calendar.c.
Referenced by load_config(), and load_tech_calendars().
struct ast_custom_function calendar_event_function [static] |
Initial value:
{ .name = "CALENDAR_EVENT", .read = calendar_event_read, }
Definition at line 1620 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function calendar_query_function [static] |
Initial value:
{ .name = "CALENDAR_QUERY", .read = calendar_query_exec, }
Definition at line 1191 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function calendar_query_result_function [static] |
Initial value:
{ .name = "CALENDAR_QUERY_RESULT", .read = calendar_query_result_exec, }
Definition at line 1302 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function calendar_write_function [static] |
Initial value:
{ .name = "CALENDAR_WRITE", .write = calendar_write_exec, }
Definition at line 1409 of file res_calendar.c.
Referenced by load_module(), and unload_module().
struct ao2_container* calendars [static] |
ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } [static] |
Definition at line 234 of file res_calendar.c.
struct ast_datastore_info event_notification_datastore [static] |
Initial value:
{ .type = "EventNotification", .destroy = event_notification_destroy, .duplicate = event_notification_duplicate, }
Definition at line 213 of file res_calendar.c.
Referenced by calendar_event_read(), and do_notify().
struct ast_datastore_info eventlist_datastore_info [static] |
Initial value:
{ .type = "CalendarEventList", .destroy = eventlist_destroy, .duplicate = eventlist_duplicate, }
Definition at line 219 of file res_calendar.c.
Referenced by calendar_query_exec(), and calendar_query_result_exec().
struct ast_channel_tech null_tech [static] |
Initial value:
{ .type = "NULL", .description = "Null channel (should not see this)", .write = null_chan_write, }
Definition at line 663 of file res_calendar.c.
ast_cond_t refresh_condition [static] |
Definition at line 205 of file res_calendar.c.
pthread_t refresh_thread = AST_PTHREADT_NULL [static] |
Definition at line 203 of file res_calendar.c.
ast_mutex_t refreshlock [static] |
Definition at line 204 of file res_calendar.c.
Referenced by caldav_load_calendar(), do_refresh(), ewscal_load_calendar(), exchangecal_load_calendar(), ical_load_calendar(), load_module(), and schedule_calendar_event().
ast_mutex_t reloadlock [static] |
Definition at line 206 of file res_calendar.c.
struct sched_context* sched [static] |
Definition at line 202 of file res_calendar.c.