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