Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Functions | Variables
res_calendar.c File Reference

Calendaring API. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/config.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"
#include "asterisk/format_cache.h"
Include dependency graph for res_calendar.c:

Go to the source code of this file.

Data Structures

struct  evententry
 
struct  eventlist
 
struct  techs
 

Macros

#define CALENDAR_BUCKETS   19
 
#define FORMAT   "%-20.20s %-10.10s %-6.6s\n"
 
#define FORMAT   "%-10.10s %-30.30s\n"
 
#define FORMAT   "%-18.18s : %-20.20s\n"
 
#define FORMAT2   "%-12.12s: %-40.60s\n"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int add_event_to_list (struct eventlist *events, struct ast_calendar_event *event, time_t start, time_t end)
 
static int add_new_event_cb (void *obj, void *arg, int flags)
 
static const char * ast_calendar_busy_state_to_str (enum ast_calendar_busy_state busy_state)
 
void ast_calendar_clear_events (struct ast_calendar *cal)
 Remove all events from calendar. More...
 
const struct ast_configast_calendar_config_acquire (void)
 Grab and lock pointer to the calendar config (read only) More...
 
void ast_calendar_config_release (void)
 Release the calendar config. More...
 
struct ast_calendar_eventast_calendar_event_alloc (struct ast_calendar *cal)
 Allocate an astobj2 ast_calendar_event object. More...
 
struct ao2_containerast_calendar_event_container_alloc (void)
 Allocate an astobj2 container for ast_calendar_event objects. More...
 
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. More...
 
int ast_calendar_register (struct ast_calendar_tech *tech)
 Register a new calendar technology. More...
 
struct ast_calendar_eventast_calendar_unref_event (struct ast_calendar_event *event)
 Unreference an ast_calendar_event. More...
 
void ast_calendar_unregister (struct ast_calendar_tech *tech)
 Unregister a new calendar technology. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ast_calendarbuild_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. More...
 
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_eventdestroy_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_calendarfind_calendar (const char *name)
 
static struct ast_calendar_eventfind_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) More...
 
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. More...
 
static char * handle_show_calendars_types (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list of all calendars types currently loaded on the backend. More...
 
static int load_config (int reload)
 
static int load_module (void)
 Load the module. More...
 
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_calendarunref_calendar (struct ast_calendar *cal)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Calendar integration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function calendar_busy_function
 
static struct ast_cli_entry calendar_cli []
 
static struct ast_configcalendar_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_containercalendars
 
static ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
 
static const struct ast_datastore_info event_notification_datastore
 
static const struct ast_datastore_info eventlist_datastore_info
 
static int module_unloading
 
static const struct ast_channel_tech null_tech
 
static ast_cond_t refresh_condition
 
static pthread_t refresh_thread = AST_PTHREADT_NULL
 
static ast_mutex_t refreshlock
 
static ast_mutex_t reloadlock
 
static struct ast_sched_contextsched
 
static struct techs techs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 

Detailed Description

Calendaring API.

Todo:

Support responding to a meeting invite

Support writing attendees

Definition in file res_calendar.c.

Macro Definition Documentation

◆ CALENDAR_BUCKETS

#define CALENDAR_BUCKETS   19

Definition at line 222 of file res_calendar.c.

◆ FORMAT [1/3]

#define FORMAT   "%-20.20s %-10.10s %-6.6s\n"

◆ FORMAT [2/3]

#define FORMAT   "%-10.10s %-30.30s\n"

◆ FORMAT [3/3]

#define FORMAT   "%-18.18s : %-20.20s\n"

◆ FORMAT2

#define FORMAT2   "%-12.12s: %-40.60s\n"

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1969 of file res_calendar.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1969 of file res_calendar.c.

◆ add_event_to_list()

static int add_event_to_list ( struct eventlist events,
struct ast_calendar_event event,
time_t  start,
time_t  end 
)
static

Definition at line 1126 of file res_calendar.c.

1127{
1128 struct evententry *entry, *iter;
1129 long event_startdiff = labs(start - event->start);
1130 long event_enddiff = labs(end - event->end);
1131 int i = 0;
1132
1133 if (!(entry = ast_calloc(1, sizeof(*entry)))) {
1134 ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1135 return -1;
1136 }
1137
1138 entry->event = event;
1139 ao2_ref(event, +1);
1140
1141 if (start == end) {
1143 long startdiff = labs(iter->event->start - start);
1144
1145 ast_debug(10, "Comparing %s with startdiff %ld to %s with startdiff %ld\n", event->summary, event_startdiff, iter->event->summary, startdiff);
1146 ++i;
1147 if (startdiff > event_startdiff) {
1149 return i;
1150 }
1151 if (startdiff == event_startdiff) {
1152 long enddiff = labs(iter->event->end - end);
1153
1154 if (enddiff > event_enddiff) {
1156 return i;
1157 }
1158 if (event_startdiff == enddiff) {
1159 if (strcmp(event->uid, iter->event->uid) < 0) {
1161 return i;
1162 }
1163 }
1164 }
1165 }
1167
1169
1170 return i;
1171 }
1172
1174 ++i;
1175 if (iter->event->start > event->start) {
1177 return i;
1178 }
1179
1180 if (iter->event->start == event->start) {
1181 if ((iter->event->end - iter->event->start) == (event->end - event->start)) {
1182 if (strcmp(event->uid, iter->event->uid) < 0) {
1184 return i;
1185 }
1186 }
1187 if ((iter->event->end - iter->event->start) < (event->end - event->start)) {
1189 return i;
1190 }
1191 }
1192 }
1194
1196
1197 return i;
1198}
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
char * end
Definition: eagi_proxy.c:73
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
Definition: linkedlists.h:599
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
const ast_string_field uid
Definition: calendar.h:103
const ast_string_field summary
Definition: calendar.h:103
Definition: search.h:40
Definition: astman.c:222
struct ast_calendar_event * event
Definition: res_calendar.c:250
struct evententry::@423 list

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, end, 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().

◆ add_new_event_cb()

static int add_new_event_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1050 of file res_calendar.c.

1051{
1052 struct ast_calendar_event *new_event = obj;
1053 struct ao2_container *events = arg;
1054
1055 ao2_link(events, new_event);
1056 schedule_calendar_event(new_event->owner, new_event, NULL);
1057 return CMP_MATCH;
1058}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ CMP_MATCH
Definition: astobj2.h:1027
static int schedule_calendar_event(struct ast_calendar *cal, struct ast_calendar_event *old_event, struct ast_calendar_event *cmp_event)
Definition: res_calendar.c:956
#define NULL
Definition: resample.c:96
Generic container type.
Calendar events.
Definition: calendar.h:95
struct ast_calendar * owner
Definition: calendar.h:105

References ao2_link, CMP_MATCH, events, NULL, ast_calendar_event::owner, and schedule_calendar_event().

Referenced by ast_calendar_merge_events().

◆ ast_calendar_busy_state_to_str()

static const char * ast_calendar_busy_state_to_str ( enum ast_calendar_busy_state  busy_state)
static

Definition at line 1611 of file res_calendar.c.

1612{
1613 switch (busy_state) {
1615 return "Free";
1617 return "Busy (Tentative)";
1619 return "Busy";
1620 default:
1621 return "Unknown (Busy)";
1622 }
1623}
@ AST_CALENDAR_BS_FREE
Definition: calendar.h:84
@ AST_CALENDAR_BS_BUSY_TENTATIVE
Definition: calendar.h:85
@ AST_CALENDAR_BS_BUSY
Definition: calendar.h:86

References AST_CALENDAR_BS_BUSY, AST_CALENDAR_BS_BUSY_TENTATIVE, and AST_CALENDAR_BS_FREE.

Referenced by handle_show_calendar().

◆ ast_calendar_clear_events()

void ast_calendar_clear_events ( struct ast_calendar cal)

Remove all events from calendar.

Parameters
calcalendar whose events need to be cleared

Definition at line 662 of file res_calendar.c.

663{
664 ast_debug(3, "Clearing all events for calendar %s\n", cal->name);
665
667}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
static int clear_events_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:653
struct ao2_container * events
Definition: calendar.h:140
const ast_string_field name
Definition: calendar.h:129

References ao2_callback, ast_debug, clear_events_cb(), ast_calendar::events, ast_calendar::name, NULL, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by calendar_destructor().

◆ ast_calendar_config_acquire()

const struct ast_config * ast_calendar_config_acquire ( void  )

Grab and lock pointer to the calendar config (read only)

Note
ast_calendar_config_release must be called when finished with the pointer
Returns
the parsed calendar config

Definition at line 260 of file res_calendar.c.

261{
263
264 if (!calendar_config) {
266 return NULL;
267 }
268
269 return calendar_config;
270}
#define ast_rwlock_rdlock(a)
Definition: lock.h:235
#define ast_rwlock_unlock(a)
Definition: lock.h:234
static struct ast_config * calendar_config
Definition: res_calendar.c:257
static ast_rwlock_t config_lock
Definition: res_calendar.c:258

References ast_rwlock_rdlock, ast_rwlock_unlock, calendar_config, config_lock, and NULL.

Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().

◆ ast_calendar_config_release()

void ast_calendar_config_release ( void  )

Release the calendar config.

Definition at line 272 of file res_calendar.c.

273{
275}

References ast_rwlock_unlock, and config_lock.

Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().

◆ ast_calendar_event_alloc()

struct ast_calendar_event * ast_calendar_event_alloc ( struct ast_calendar cal)

Allocate an astobj2 ast_calendar_event object.

Parameters
calcalendar to allocate an event for
Returns
a new, initialized calendar event

Definition at line 669 of file res_calendar.c.

670{
672 if (!(event = ao2_alloc(sizeof(*event), calendar_event_destructor))) {
673 return NULL;
674 }
675
676 if (ast_string_field_init(event, 32)) {
678 return NULL;
679 }
680
681 event->owner = cal;
682 event->notify_sched = -1;
683 event->bs_start_sched = -1;
684 event->bs_end_sched = -1;
685
686 AST_LIST_HEAD_INIT_NOLOCK(&event->attendees);
687
688 return event;
689}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:323
static void calendar_event_destructor(void *obj)
Definition: res_calendar.c:611
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359

References ao2_alloc, ast_calendar_unref_event(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, calendar_event_destructor(), and NULL.

Referenced by caldav_add_event(), calendar_write_exec(), icalendar_add_event(), parse_tag(), and startelm().

◆ ast_calendar_event_container_alloc()

struct ao2_container * ast_calendar_event_container_alloc ( void  )

Allocate an astobj2 container for ast_calendar_event objects.

Returns
a new event container

Definition at line 691 of file res_calendar.c.

692{
695}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
static int event_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:303
#define CALENDAR_BUCKETS
Definition: res_calendar.c:222
static int event_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:309

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, CALENDAR_BUCKETS, event_cmp_fn(), event_hash_fn(), and NULL.

Referenced by caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), and ical_load_calendar().

◆ ast_calendar_merge_events()

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.

Parameters
calcalendar containing the events to be merged
new_eventsan oa2 container of events to be merged into cal->events

Definition at line 1060 of file res_calendar.c.

1061{
1062 /* Loop through all events attached to the calendar. If there is a matching new event
1063 * merge its data over and handle any schedule changes that need to be made. Then remove
1064 * the new_event from new_events so that we are left with only new_events that we can add later. */
1066
1067 /* Now, we should only have completely new events in new_events. Loop through and add them */
1069}
static int add_new_event_cb(void *obj, void *arg, int flags)
static int merge_events_cb(void *obj, void *arg, int flags)

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().

◆ ast_calendar_register()

int ast_calendar_register ( struct ast_calendar_tech tech)

Register a new calendar technology.

Parameters
techcalendar technology to register
Return values
0success
-1failure

Definition at line 551 of file res_calendar.c.

552{
553 struct ast_calendar_tech *iter;
554
555 if (!calendar_config) {
556 ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
557 return -1;
558 }
559
561 AST_LIST_TRAVERSE(&techs, iter, list) {
562 if(!strcasecmp(tech->type, iter->type)) {
563 ast_log(LOG_WARNING, "Already have a handler for calendar type '%s'\n", tech->type);
565 return -1;
566 }
567 }
571
572 ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description);
573
574 return load_tech_calendars(tech);
575}
#define ast_verb(level,...)
#define LOG_WARNING
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
#define ast_module_user_add(chan)
Definition: module.h:426
static int load_tech_calendars(struct ast_calendar_tech *tech)
Definition: res_calendar.c:515
Individual calendaring technology data.
Definition: calendar.h:71
struct ast_calendar_tech::@201 list
const char * description
Definition: calendar.h:73
const char * type
Definition: calendar.h:72
struct ast_module_user * user
Definition: calendar.h:75

References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_module_user_add, ast_verb, calendar_config, ast_calendar_tech::description, ast_calendar_tech::list, load_tech_calendars(), LOG_WARNING, NULL, ast_calendar_tech::type, and ast_calendar_tech::user.

Referenced by load_module().

◆ ast_calendar_unref_event()

struct ast_calendar_event * ast_calendar_unref_event ( struct ast_calendar_event event)

◆ ast_calendar_unregister()

void ast_calendar_unregister ( struct ast_calendar_tech tech)

Unregister a new calendar technology.

Parameters
techcalendar technology to unregister

Definition at line 589 of file res_calendar.c.

590{
591 struct ast_calendar_tech *iter;
592
595 if (iter != tech) {
596 continue;
597 }
598
600
603 ast_verb(2, "Unregistered calendar type '%s'\n", tech->type);
604 break;
605 }
608
609}
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define ast_module_user_remove(user)
Definition: module.h:427
static int match_caltech_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:577
static struct ao2_container * calendars
Definition: res_calendar.c:224

References ao2_callback, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_module_user_remove, ast_verb, calendars, ast_calendar_tech::list, match_caltech_cb(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_calendar_tech::type, and ast_calendar_tech::user.

Referenced by load_tech_calendars(), and unload_module().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1969 of file res_calendar.c.

◆ build_calendar()

static struct ast_calendar * build_calendar ( struct ast_config cfg,
const char *  cat,
const struct ast_calendar_tech tech 
)
static

Create new calendar, old will be removed during reload

Definition at line 402 of file res_calendar.c.

403{
404 struct ast_calendar *cal;
405 struct ast_variable *v, *last = NULL;
406 int new_calendar = 0;
407
408 cal = find_calendar(cat);
409 if (cal && cal->fetch_again_at_reload) {
410 /** Create new calendar, old will be removed during reload */
411 cal = unref_calendar(cal);
412 }
413 if (!cal) {
414 new_calendar = 1;
415 if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) {
416 ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n");
417 return NULL;
418 }
419
422 if (!cal->events) {
423 ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat);
424 cal = unref_calendar(cal);
425 return NULL;
426 }
427
428 if (ast_string_field_init(cal, 32)) {
429 ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat);
430 cal = unref_calendar(cal);
431 return NULL;
432 }
433 } else {
434 cal->pending_deletion = 0;
435 }
436
437 ast_string_field_set(cal, name, cat);
438 cal->tech = tech;
439
440 cal->refresh = 3600;
441 cal->timeframe = 60;
442 cal->notify_waittime = 30000;
443 cal->fetch_again_at_reload = 0;
444
445 for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
446 if (!strcasecmp(v->name, "autoreminder")) {
447 cal->autoreminder = atoi(v->value);
448 } else if (!strcasecmp(v->name, "channel")) {
450 } else if (!strcasecmp(v->name, "context")) {
451 ast_string_field_set(cal, notify_context, v->value);
452 } else if (!strcasecmp(v->name, "extension")) {
453 ast_string_field_set(cal, notify_extension, v->value);
454 } else if (!strcasecmp(v->name, "waittime")) {
455 int i = atoi(v->value);
456 if (i > 0) {
457 cal->notify_waittime = 1000 * i;
458 }
459 } else if (!strcasecmp(v->name, "app")) {
460 ast_string_field_set(cal, notify_app, v->value);
461 } else if (!strcasecmp(v->name, "appdata")) {
462 ast_string_field_set(cal, notify_appdata, v->value);
463 } else if (!strcasecmp(v->name, "refresh")) {
464 cal->refresh = atoi(v->value);
465 } else if (!strcasecmp(v->name, "fetch_again_at_reload")) {
467 } else if (!strcasecmp(v->name, "timeframe")) {
468 cal->timeframe = atoi(v->value);
469 } else if (!strcasecmp(v->name, "setvar")) {
470 char *name, *value;
471 struct ast_variable *var;
472
473 if ((name = (value = ast_strdup(v->value)))) {
474 strsep(&value, "=");
475 if (value) {
477 if (last) {
478 last->next = var;
479 } else {
480 cal->vars = var;
481 }
482 last = var;
483 }
484 } else {
485 ast_log(LOG_WARNING, "Malformed argument. Should be '%s: variable=value'\n", v->name);
486 }
487 ast_free(name);
488 }
489 }
490 }
491
492 if (cal->autoreminder && ast_strlen_zero(cal->notify_channel)) {
494 "You have set 'autoreminder' but not 'channel' for calendar '%s.' "
495 "Notifications will not occur.\n",
496 cal->name);
497 }
498
499 if (new_calendar) {
501 ast_cond_init(&cal->unload, NULL);
502 ao2_link(calendars, cal);
503 if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) {
504 /* If we start failing to create threads, go ahead and return NULL
505 * and the tech module will be unregistered
506 */
507 ao2_unlink(calendars, cal);
508 cal = unref_calendar(cal);
509 }
510 }
511
512 return cal;
513}
struct sla_ringing_trunk * last
Definition: app_sla.c:332
#define var
Definition: ast_expr2f.c:605
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
static const char name[]
Definition: format_mp3.c:68
char * strsep(char **str, const char *delims)
#define ast_variable_new(name, value, filename)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_cond_init(cond, attr)
Definition: lock.h:201
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:277
static void calendar_destructor(void *obj)
Definition: res_calendar.c:329
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:295
static int notify_channel(void *obj)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
void *(* load_calendar)(void *data)
Definition: calendar.h:77
Asterisk calendar structure.
Definition: calendar.h:119
pthread_t thread
Definition: calendar.h:136
struct ast_variable * vars
Definition: calendar.h:130
const struct ast_calendar_tech * tech
Definition: calendar.h:120
int autoreminder
Definition: calendar.h:131
int timeframe
Definition: calendar.h:135
int fetch_again_at_reload
Definition: calendar.h:134
unsigned int pending_deletion
Definition: calendar.h:139
const ast_string_field notify_channel
Definition: calendar.h:129
ast_cond_t unload
Definition: calendar.h:137
int notify_waittime
Definition: calendar.h:132
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct sla_ringing_trunk * next
Definition: app_sla.c:308
int value
Definition: syslog.c:37
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_link, ao2_unlink, ast_cond_init, ast_free, ast_log, ast_pthread_create, AST_PTHREADT_NULL, ast_strdup, ast_string_field_init, ast_string_field_set, ast_strip(), ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_new, ast_calendar::autoreminder, CALENDAR_BUCKETS, calendar_destructor(), calendars, event_cmp_fn(), event_hash_fn(), ast_calendar::events, ast_calendar::fetch_again_at_reload, find_calendar(), last, ast_calendar_tech::load_calendar, LOG_ERROR, LOG_WARNING, name, ast_calendar::name, ast_variable::name, sla_ringing_trunk::next, ast_variable::next, ast_calendar::notify_channel, notify_channel(), ast_calendar::notify_waittime, NULL, ast_calendar::pending_deletion, ast_calendar::refresh, strsep(), ast_calendar::tech, ast_calendar::thread, ast_calendar::timeframe, ast_calendar::unload, unref_calendar(), ast_variable::value, value, var, and ast_calendar::vars.

Referenced by load_tech_calendars().

◆ calendar_busy_callback()

static int calendar_busy_callback ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 360 of file res_calendar.c.

361{
362 struct ast_calendar_event *event = obj;
363 int *is_busy = arg;
364 struct timeval tv = ast_tvnow();
365
366 if (tv.tv_sec >= event->start && tv.tv_sec <= event->end && event->busy_state > AST_CALENDAR_BS_FREE) {
367 *is_busy = 1;
368 return CMP_STOP;
369 }
370
371 return 0;
372}
@ CMP_STOP
Definition: astobj2.h:1028
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References AST_CALENDAR_BS_FREE, ast_tvnow(), and CMP_STOP.

Referenced by calendar_is_busy().

◆ calendar_busy_exec()

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 1099 of file res_calendar.c.

1100{
1101 struct ast_calendar *cal;
1102
1103 if (ast_strlen_zero(data)) {
1104 ast_log(LOG_WARNING, "CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n");
1105 return -1;
1106 }
1107
1108 cal = find_calendar(data);
1109
1110 if (!cal) {
1111 ast_log(LOG_WARNING, "Could not find calendar '%s'\n", data);
1112 return -1;
1113 }
1114
1115 strcpy(buf, calendar_is_busy(cal) ? "1" : "0");
1116 cal = unref_calendar(cal);
1117
1118 return 0;
1119}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:374

References ast_log, ast_strlen_zero(), buf, calendar_is_busy(), find_calendar(), LOG_WARNING, and unref_calendar().

◆ calendar_cmp_fn()

static int calendar_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 289 of file res_calendar.c.

290{
291 const struct ast_calendar *one = obj, *two = arg;
292 return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP: 0;
293}

References CMP_MATCH, CMP_STOP, and ast_calendar::name.

Referenced by load_module().

◆ calendar_destructor()

static void calendar_destructor ( void *  obj)
static

Definition at line 329 of file res_calendar.c.

330{
331 struct ast_calendar *cal = obj;
332
333 ast_debug(3, "Destroying calendar %s\n", cal->name);
334
335 ao2_lock(cal);
336 cal->unloading = 1;
337 ast_cond_signal(&cal->unload);
338 pthread_join(cal->thread, NULL);
339 if (cal->tech_pvt) {
340 cal->tech_pvt = cal->tech->unref_calendar(cal->tech_pvt);
341 }
345 ao2_ref(cal->events, -1);
346 ao2_unlock(cal);
347}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_cond_signal(cond)
Definition: lock.h:203
void ast_calendar_clear_events(struct ast_calendar *cal)
Remove all events from calendar.
Definition: res_calendar.c:662
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
void *(* unref_calendar)(void *obj)
Definition: calendar.h:78
void * tech_pvt
Definition: calendar.h:121
unsigned int unloading
Definition: calendar.h:138

References ao2_lock, ao2_ref, ao2_unlock, ast_calendar_clear_events(), ast_cond_signal, ast_debug, ast_string_field_free_memory, ast_variables_destroy(), ast_calendar::events, ast_calendar::name, NULL, ast_calendar::tech, ast_calendar::tech_pvt, ast_calendar::thread, ast_calendar::unload, ast_calendar::unloading, ast_calendar_tech::unref_calendar, and ast_calendar::vars.

Referenced by build_calendar().

◆ calendar_devstate_change()

static int calendar_devstate_change ( const void *  data)
static

Definition at line 894 of file res_calendar.c.

895{
896 struct ast_calendar_event *event = (struct ast_calendar_event *)data;
897 struct timeval now = ast_tvnow();
898 int is_end_event;
899
900 if (!event) {
901 ast_log(LOG_WARNING, "Event was NULL!\n");
902 return 0;
903 }
904
905 ao2_ref(event, +1);
906
907 is_end_event = event->end <= now.tv_sec;
908
909 if (is_end_event) {
910 event->bs_end_sched = -1;
911 } else {
912 event->bs_start_sched = -1;
913 }
914
915 /* We can have overlapping events, so ignore the event->busy_state and check busy state
916 * based on all events in the calendar */
917 if (!calendar_is_busy(event->owner)) {
919 } else {
921 }
922
924
925 return 0;
926}
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
@ AST_DEVICE_BUSY
Definition: devicestate.h:56
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54

References ao2_ref, ast_calendar_unref_event(), AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log, ast_tvnow(), calendar_is_busy(), and LOG_WARNING.

Referenced by schedule_calendar_event().

◆ calendar_event_destructor()

static void calendar_event_destructor ( void *  obj)
static

Definition at line 611 of file res_calendar.c.

612{
613 struct ast_calendar_event *event = obj;
614 struct ast_calendar_attendee *attendee;
615
616 ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name);
618 while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) {
619 if (attendee->data) {
620 ast_free(attendee->data);
621 }
622 ast_free(attendee);
623 }
624}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
struct ast_calendar_attendee * next
Definition: calendar.h:91

References ast_debug, ast_free, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_calendar_attendee::data, and ast_calendar_attendee::next.

Referenced by ast_calendar_event_alloc().

◆ calendar_event_notify()

static int calendar_event_notify ( const void *  data)
static

Definition at line 870 of file res_calendar.c.

871{
872 struct ast_calendar_event *event = (void *)data;
873 int res = -1;
874 pthread_t notify_thread = AST_PTHREADT_NULL;
875
876 if (!(event && event->owner)) {
877 ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
878 return res;
879 }
880
881 ao2_ref(event, +1);
882 event->notify_sched = -1;
883
884 if (ast_pthread_create_background(&notify_thread, NULL, do_notify, event) < 0) {
885 ast_log(LOG_ERROR, "Could not create notification thread\n");
886 return res;
887 }
888
889 res = 0;
890
891 return res;
892}
static void * do_notify(void *data)
Definition: res_calendar.c:743
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

References ao2_ref, ast_log, ast_pthread_create_background, AST_PTHREADT_NULL, do_notify(), LOG_ERROR, and NULL.

Referenced by schedule_calendar_event().

◆ calendar_event_read()

static int calendar_event_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1739 of file res_calendar.c.

1740{
1741 struct ast_datastore *datastore;
1742 struct ast_calendar_event *event;
1743
1744 if (!chan) {
1745 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1746 return -1;
1747 }
1748
1749 if (ast_strlen_zero(data)) {
1750 ast_log(LOG_WARNING, "%s requires an argument\n", cmd);
1751 return -1;
1752 }
1753
1754 ast_channel_lock(chan);
1755 if (!(datastore = ast_channel_datastore_find(chan, &event_notification_datastore, NULL))) {
1756 ast_log(LOG_WARNING, "There is no event notification datastore on '%s'!\n", ast_channel_name(chan));
1757 ast_channel_unlock(chan);
1758 return -1;
1759 }
1760 ast_channel_unlock(chan);
1761
1762 if (!(event = datastore->data)) {
1763 ast_log(LOG_WARNING, "The datastore contains no data!\n");
1764 return -1;
1765 }
1766
1767 if (!strcasecmp(data, "summary")) {
1768 ast_copy_string(buf, event->summary, len);
1769 } else if (!strcasecmp(data, "description")) {
1770 ast_copy_string(buf, event->description, len);
1771 } else if (!strcasecmp(data, "organizer")) {
1772 ast_copy_string(buf, event->organizer, len);
1773 } else if (!strcasecmp(data, "location")) {
1774 ast_copy_string(buf, event->location, len);
1775 } else if (!strcasecmp(data, "categories")) {
1776 ast_copy_string(buf, event->categories, len);
1777 } else if (!strcasecmp(data, "priority")) {
1778 snprintf(buf, len, "%d", event->priority);
1779 } else if (!strcasecmp(data, "calendar")) {
1780 ast_copy_string(buf, event->owner->name, len);
1781 } else if (!strcasecmp(data, "uid")) {
1782 ast_copy_string(buf, event->uid, len);
1783 } else if (!strcasecmp(data, "start")) {
1784 snprintf(buf, len, "%ld", (long)event->start);
1785 } else if (!strcasecmp(data, "end")) {
1786 snprintf(buf, len, "%ld", (long)event->end);
1787 } else if (!strcasecmp(data, "busystate")) {
1788 snprintf(buf, len, "%u", event->busy_state);
1789 } else if (!strcasecmp(data, "attendees")) {
1791 }
1792
1793
1794 return 0;
1795}
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
static const struct ast_datastore_info event_notification_datastore
Definition: res_calendar.c:237
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), ast_log, ast_strlen_zero(), buf, calendar_join_attendees(), ast_datastore::data, event_notification_datastore, len(), LOG_WARNING, and NULL.

◆ calendar_hash_fn()

static int calendar_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 283 of file res_calendar.c.

284{
285 const struct ast_calendar *cal = obj;
286 return ast_str_case_hash(cal->name);
287}
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303

References ast_str_case_hash(), and ast_calendar::name.

Referenced by load_module().

◆ calendar_is_busy()

static int calendar_is_busy ( struct ast_calendar cal)
static

Definition at line 374 of file res_calendar.c.

375{
376 int is_busy = 0;
377
379
380 return is_busy;
381}
static int calendar_busy_callback(void *obj, void *arg, int flags)
Definition: res_calendar.c:360

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().

◆ calendar_join_attendees()

static void calendar_join_attendees ( struct ast_calendar_event event,
char *  buf,
size_t  len 
)
static

Definition at line 1311 of file res_calendar.c.

1312{
1313 struct ast_str *tmp;
1314 struct ast_calendar_attendee *attendee;
1315
1316 if (!(tmp = ast_str_create(32))) {
1317 ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n");
1318 return;
1319 }
1320
1321 AST_LIST_TRAVERSE(&event->attendees, attendee, next) {
1322 ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data);
1323 }
1324
1326 ast_free(tmp);
1327}
static int tmp()
Definition: bt_open.c:389
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
Support for dynamic strings.
Definition: strings.h:623

References ast_copy_string(), ast_free, AST_LIST_FIRST, AST_LIST_TRAVERSE, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, buf, ast_calendar_attendee::data, len(), LOG_ERROR, ast_calendar_attendee::next, and tmp().

Referenced by calendar_event_read(), and calendar_query_result_exec().

◆ calendar_query_exec()

static int calendar_query_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1220 of file res_calendar.c.

1221{
1222 struct ast_calendar *cal;
1223 struct ao2_iterator i;
1224 struct ast_calendar_event *event;
1225 struct eventlist *events;
1226 time_t start = INT_MIN, end = INT_MAX;
1227 struct ast_datastore *eventlist_datastore;
1229 AST_APP_ARG(calendar);
1230 AST_APP_ARG(start);
1232 );
1233
1234 if (!chan) {
1235 ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd);
1236 return -1;
1237 }
1238
1240
1241 if (ast_strlen_zero(args.calendar)) {
1242 ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd);
1243 return -1;
1244 }
1245
1246 if (!(cal = find_calendar(args.calendar))) {
1247 ast_log(LOG_WARNING, "Unknown calendar '%s'\n", args.calendar);
1248 return -1;
1249 }
1250
1251 if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) {
1252 ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1253 cal = unref_calendar(cal);
1254 return -1;
1255 }
1256
1257 if (!ast_strlen_zero(args.start)) {
1258 start = atoi(args.start);
1259 }
1260
1261 if (!ast_strlen_zero(args.end)) {
1262 end = atoi(args.end);
1263 }
1264
1265 i = ao2_iterator_init(cal->events, 0);
1266 while ((event = ao2_iterator_next(&i))) {
1267 if (!(start > event->end || end < event->start)) {
1268 ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end);
1269 if (add_event_to_list(events, event, start, end) < 0) {
1271 cal = unref_calendar(cal);
1272 ao2_ref(events, -1);
1274 return -1;
1275 }
1276 }
1277
1279 }
1281
1282 ast_channel_lock(chan);
1283 do {
1286 ast_channel_unlock(chan);
1287
1288 if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) {
1289 ast_log(LOG_ERROR, "Could not allocate datastore!\n");
1290 cal = unref_calendar(cal);
1291 ao2_ref(events, -1);
1292 return -1;
1293 }
1294
1295 eventlist_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1296 eventlist_datastore->data = events;
1297
1298 ast_channel_lock(chan);
1299 ast_channel_datastore_add(chan, eventlist_datastore);
1300 ast_channel_unlock(chan);
1301
1302 cal = unref_calendar(cal);
1303 return 0;
1304}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:192
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static void eventlist_destructor(void *obj)
Definition: res_calendar.c:349
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:719
static const struct ast_datastore_info eventlist_datastore_info
Definition: res_calendar.c:243
static int add_event_to_list(struct eventlist *events, struct ast_calendar_event *event, time_t start, time_t end)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
unsigned int inheritance
Definition: datastore.h:69
const char * args

References add_event_to_list(), ao2_alloc, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, args, AST_APP_ARG, ast_calendar_unref_event(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero(), buf, ast_datastore::data, DATASTORE_INHERIT_FOREVER, end, eventlist_datastore_info, eventlist_destructor(), events, ast_calendar::events, find_calendar(), generate_random_string(), ast_datastore::inheritance, len(), LOG_ERROR, LOG_WARNING, and unref_calendar().

◆ calendar_query_result_exec()

static int calendar_query_result_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1329 of file res_calendar.c.

1330{
1331 struct ast_datastore *datastore;
1332 struct eventlist *events;
1333 struct evententry *entry;
1334 int row = 1;
1335 size_t listlen = 0;
1337 AST_APP_ARG(id);
1338 AST_APP_ARG(field);
1339 AST_APP_ARG(row);
1340 );
1341
1342 if (!chan) {
1343 ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
1344 return -1;
1345 }
1346
1348
1349 if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) {
1350 ast_log(LOG_WARNING, "%s requires an id and a field", cmd);
1351 return -1;
1352 }
1353
1354 ast_channel_lock(chan);
1355 if (!(datastore = ast_channel_datastore_find(chan, &eventlist_datastore_info, args.id))) {
1356 ast_log(LOG_WARNING, "There is no event notification datastore with id '%s' on '%s'!\n", args.id, ast_channel_name(chan));
1357 ast_channel_unlock(chan);
1358 return -1;
1359 }
1360 ast_channel_unlock(chan);
1361
1362 if (!(events = datastore->data)) {
1363 ast_log(LOG_WARNING, "The datastore contains no data!\n");
1364 return -1;
1365 }
1366
1367 if (!ast_strlen_zero(args.row)) {
1368 row = atoi(args.row);
1369 }
1370
1372 listlen++;
1373 }
1374
1375 if (!strcasecmp(args.field, "getnum")) {
1376 snprintf(buf, len, "%zu", listlen);
1377 return 0;
1378 }
1379
1381 if (--row) {
1382 continue;
1383 }
1384 if (!strcasecmp(args.field, "summary")) {
1385 ast_copy_string(buf, entry->event->summary, len);
1386 } else if (!strcasecmp(args.field, "description")) {
1387 ast_copy_string(buf, entry->event->description, len);
1388 } else if (!strcasecmp(args.field, "organizer")) {
1389 ast_copy_string(buf, entry->event->organizer, len);
1390 } else if (!strcasecmp(args.field, "location")) {
1391 ast_copy_string(buf, entry->event->location, len);
1392 } else if (!strcasecmp(args.field, "categories")) {
1393 ast_copy_string(buf, entry->event->categories, len);
1394 } else if (!strcasecmp(args.field, "priority")) {
1395 snprintf(buf, len, "%d", entry->event->priority);
1396 } else if (!strcasecmp(args.field, "calendar")) {
1397 ast_copy_string(buf, entry->event->owner->name, len);
1398 } else if (!strcasecmp(args.field, "uid")) {
1399 ast_copy_string(buf, entry->event->uid, len);
1400 } else if (!strcasecmp(args.field, "start")) {
1401 snprintf(buf, len, "%ld", (long) entry->event->start);
1402 } else if (!strcasecmp(args.field, "end")) {
1403 snprintf(buf, len, "%ld", (long) entry->event->end);
1404 } else if (!strcasecmp(args.field, "busystate")) {
1405 snprintf(buf, len, "%u", entry->event->busy_state);
1406 } else if (!strcasecmp(args.field, "attendees")) {
1408 } else {
1409 ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field);
1410 }
1411 break;
1412 }
1413
1414 return 0;
1415}

References args, AST_APP_ARG, ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero(), buf, calendar_join_attendees(), ast_datastore::data, eventlist_datastore_info, events, len(), evententry::list, and LOG_WARNING.

◆ calendar_write_exec()

static int calendar_write_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 1422 of file res_calendar.c.

1423{
1424 int i, j, ret = -1;
1425 char *val_dup = NULL;
1426 struct ast_calendar *cal = NULL;
1427 struct ast_calendar_event *event = NULL;
1428 struct timeval tv = ast_tvnow();
1429 AST_DECLARE_APP_ARGS(fields,
1430 AST_APP_ARG(field)[10];
1431 );
1433 AST_APP_ARG(value)[10];
1434 );
1435
1436 if (!(val_dup = ast_strdup(value))) {
1437 ast_log(LOG_ERROR, "Could not allocate memory for values\n");
1438 goto write_cleanup;
1439 }
1440
1441 AST_STANDARD_APP_ARGS(fields, data);
1442 AST_STANDARD_APP_ARGS(values, val_dup);
1443
1444 /* XXX Eventually we will support unnamed calendars, so if we don't find one, we parse
1445 * for a calendar type and create it */
1446 if (!(cal = find_calendar(fields.field[0]))) {
1447 ast_log(LOG_WARNING, "Couldn't find calendar '%s'\n", fields.field[0]);
1448 goto write_cleanup;
1449 }
1450
1451 if (!(cal->tech->write_event)) {
1452 ast_log(LOG_WARNING, "Calendar '%s' has no write function!\n", cal->name);
1453 goto write_cleanup;
1454 }
1455
1456 if (!(event = ast_calendar_event_alloc(cal))) {
1457 goto write_cleanup;
1458 }
1459
1460 if (ast_strlen_zero(fields.field[0])) {
1461 ast_log(LOG_WARNING, "CALENDAR_WRITE requires a calendar name!\n");
1462 goto write_cleanup;
1463 }
1464
1465 if (fields.argc - 1 != values.argc) {
1466 ast_log(LOG_WARNING, "CALENDAR_WRITE should have the same number of fields (%u) and values (%u)!\n", fields.argc - 1, values.argc);
1467 goto write_cleanup;
1468 }
1469
1470 event->owner = cal;
1471
1472 for (i = 1, j = 0; i < fields.argc; i++, j++) {
1473 if (!strcasecmp(fields.field[i], "summary")) {
1474 ast_string_field_set(event, summary, values.value[j]);
1475 } else if (!strcasecmp(fields.field[i], "description")) {
1476 ast_string_field_set(event, description, values.value[j]);
1477 } else if (!strcasecmp(fields.field[i], "organizer")) {
1478 ast_string_field_set(event, organizer, values.value[j]);
1479 } else if (!strcasecmp(fields.field[i], "location")) {
1480 ast_string_field_set(event, location, values.value[j]);
1481 } else if (!strcasecmp(fields.field[i], "categories")) {
1483 } else if (!strcasecmp(fields.field[i], "priority")) {
1484 event->priority = atoi(values.value[j]);
1485 } else if (!strcasecmp(fields.field[i], "uid")) {
1486 ast_string_field_set(event, uid, values.value[j]);
1487 } else if (!strcasecmp(fields.field[i], "start")) {
1488 event->start = atoi(values.value[j]);
1489 } else if (!strcasecmp(fields.field[i], "end")) {
1490 event->end = atoi(values.value[j]);
1491 } else if (!strcasecmp(fields.field[i], "busystate")) {
1492 event->busy_state = atoi(values.value[j]);
1493 } else {
1494 ast_log(LOG_WARNING, "Unknown calendar event field '%s'\n", fields.field[i]);
1495 }
1496 }
1497
1498 if (!event->start) {
1499 event->start = tv.tv_sec;
1500 }
1501
1502 if (!event->end) {
1503 event->end = tv.tv_sec;
1504 }
1505
1506 if((ret = cal->tech->write_event(event))) {
1507 ast_log(LOG_WARNING, "Writing event to calendar '%s' failed!\n", cal->name);
1508 }
1509
1510write_cleanup:
1511 if (ret) {
1512 pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "0");
1513 } else {
1514 pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "1");
1515 }
1516 if (cal) {
1517 cal = unref_calendar(cal);
1518 }
1519 if (event) {
1521 }
1522 if (val_dup) {
1523 ast_free(val_dup);
1524 }
1525
1526 return ret;
1527}
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
struct ast_calendar_event * ast_calendar_event_alloc(struct ast_calendar *cal)
Allocate an astobj2 ast_calendar_event object.
Definition: res_calendar.c:669
int(* write_event)(struct ast_calendar_event *event)
Definition: calendar.h:79
struct association categories[]

References AST_APP_ARG, ast_calendar_event_alloc(), ast_calendar_unref_event(), AST_DECLARE_APP_ARGS, ast_free, ast_log, AST_STANDARD_APP_ARGS, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), categories, find_calendar(), LOG_ERROR, LOG_WARNING, ast_calendar::name, NULL, pbx_builtin_setvar_helper(), ast_calendar::tech, unref_calendar(), value, and ast_calendar_tech::write_event.

◆ calendarstate()

static enum ast_device_state calendarstate ( const char *  data)
static

Definition at line 383 of file res_calendar.c.

384{
386 struct ast_calendar *cal;
387
388 if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) {
389 return AST_DEVICE_INVALID;
390 }
391
392 if (cal->tech->is_busy) {
394 } else {
396 }
397
398 cal = unref_calendar(cal);
399 return state;
400}
enum cc_state state
Definition: ccss.c:393
ast_device_state
Device States.
Definition: devicestate.h:52
@ AST_DEVICE_INUSE
Definition: devicestate.h:55
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
int(* is_busy)(struct ast_calendar *calendar)
Definition: calendar.h:76

References AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, ast_strlen_zero(), calendar_is_busy(), find_calendar(), ast_calendar_tech::is_busy, state, ast_calendar::tech, and unref_calendar().

Referenced by load_module().

◆ cb_pending_deletion()

static int cb_pending_deletion ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 1802 of file res_calendar.c.

1803{
1804 struct ast_calendar *cal = user_data;
1805
1806 cal->pending_deletion = 1;
1807
1808 return CMP_MATCH;
1809}

References CMP_MATCH, and ast_calendar::pending_deletion.

Referenced by reload().

◆ cb_rm_pending_deletion()

static int cb_rm_pending_deletion ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 1811 of file res_calendar.c.

1812{
1813 struct ast_calendar *cal = user_data;
1814
1815 return cal->pending_deletion ? CMP_MATCH : 0;
1816}

References CMP_MATCH, and ast_calendar::pending_deletion.

Referenced by reload().

◆ clear_events_cb()

static int clear_events_cb ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 653 of file res_calendar.c.

654{
655 struct ast_calendar_event *event = user_data;
656
657 event = destroy_event(event);
658
659 return CMP_MATCH;
660}
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
Definition: res_calendar.c:628

References CMP_MATCH, and destroy_event().

Referenced by ast_calendar_clear_events().

◆ copy_event_data()

static void copy_event_data ( struct ast_calendar_event dst,
struct ast_calendar_event src 
)
static

Definition at line 928 of file res_calendar.c.

929{
930 struct ast_calendar_attendee *attendee;
931
932 ast_string_field_set(dst, summary, src->summary);
933 ast_string_field_set(dst, description, src->description);
934 ast_string_field_set(dst, organizer, src->organizer);
935 ast_string_field_set(dst, location, src->location);
936 ast_string_field_set(dst, uid, src->uid);
938 dst->priority = src->priority;
939 dst->owner = src->owner;
940 dst->start = src->start;
941 dst->end = src->end;
942 dst->alarm = src->alarm;
943 dst->busy_state = src->busy_state;
944
945 /* Delete any existing attendees */
946 while ((attendee = AST_LIST_REMOVE_HEAD(&dst->attendees, next))) {
947 ast_free(attendee);
948 }
949
950 /* Copy over the new attendees */
951 while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) {
952 AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next);
953 }
954}
enum ast_calendar_busy_state busy_state
Definition: calendar.h:109
const ast_string_field location
Definition: calendar.h:103
const ast_string_field description
Definition: calendar.h:103
const ast_string_field categories
Definition: calendar.h:103
const ast_string_field organizer
Definition: calendar.h:103
struct ast_calendar_event::attendees attendees

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, 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().

◆ destroy_event()

static struct ast_calendar_event * destroy_event ( struct ast_calendar_event event)
static

Definition at line 628 of file res_calendar.c.

629{
630 if (event->notify_sched > -1 && ast_sched_del(sched, event->notify_sched)) {
631 ast_debug(3, "Notification running, can't delete sched entry\n");
632 }
633 if (event->bs_start_sched > -1 && ast_sched_del(sched, event->bs_start_sched)) {
634 ast_debug(3, "Devicestate update (start) running, can't delete sched entry\n");
635 }
636 if (event->bs_end_sched > -1 && ast_sched_del(sched, event->bs_end_sched)) {
637 ast_debug(3, "Devicestate update (end) running, can't delete sched entry\n");
638 }
639
640 /* If an event is being deleted and we've fired an event changing the status at the beginning,
641 * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
642 if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
643 if (!calendar_is_busy(event->owner)) {
645 } else {
647 }
648 }
649
650 return NULL;
651}
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:614
Definition: sched.c:76

References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_sched_del(), calendar_is_busy(), and NULL.

Referenced by clear_events_cb(), and merge_events_cb().

◆ do_notify()

static void * do_notify ( void *  data)
static

Definition at line 743 of file res_calendar.c.

744{
745 struct ast_calendar_event *event = data;
746 struct ast_dial *dial = NULL;
747 struct ast_str *apptext = NULL, *tmpstr = NULL;
748 struct ast_datastore *datastore;
749 enum ast_dial_result res;
750 struct ast_channel *chan = NULL;
751 struct ast_variable *itervar;
752 char *tech, *dest;
753 char buf[33];
754 struct ast_format_cap *caps;
755
756 tech = ast_strdupa(event->owner->notify_channel);
757
758 if ((dest = strchr(tech, '/'))) {
759 *dest = '\0';
760 dest++;
761 } else {
762 ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
763 goto notify_cleanup;
764 }
765
766 if (!(dial = ast_dial_create())) {
767 ast_log(LOG_ERROR, "Could not create dial structure\n");
768 goto notify_cleanup;
769 }
770
771 if (ast_dial_append(dial, tech, dest, NULL) < 0) {
772 ast_log(LOG_ERROR, "Could not append channel\n");
773 goto notify_cleanup;
774 }
775
776 ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
778
779 if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, NULL, NULL, 0, "Calendar/%s-%s", event->owner->name, buf))) {
780 ast_log(LOG_ERROR, "Could not allocate notification channel\n");
781 goto notify_cleanup;
782 }
783
789
791 if (!caps) {
792 ast_log(LOG_ERROR, "Could not allocate capabilities, notification not being sent!\n");
793 goto notify_cleanup;
794 }
797 ao2_ref(caps, -1);
798
799 ast_channel_unlock(chan);
800
802 ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
803 goto notify_cleanup;
804 }
805
806 datastore->data = event;
808
809 ao2_ref(event, +1);
810
811 ast_channel_lock(chan);
812 res = ast_channel_datastore_add(chan, datastore);
813 ast_channel_unlock(chan);
814
815 if (!(tmpstr = ast_str_create(32))) {
816 goto notify_cleanup;
817 }
818
819 for (itervar = event->owner->vars; itervar; itervar = itervar->next) {
820 ast_str_substitute_variables(&tmpstr, 0, chan, itervar->value);
821 pbx_builtin_setvar_helper(chan, itervar->name, ast_str_buffer(tmpstr));
822 }
823
824 if (!(apptext = ast_str_create(32))) {
825 goto notify_cleanup;
826 }
827
828 if (!ast_strlen_zero(event->owner->notify_app)) {
829 ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata);
831 } else {
832 }
833
834 ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name);
835 res = ast_dial_run(dial, chan, 0);
836
837 if (res != AST_DIAL_RESULT_ANSWERED) {
838 ast_verb(3, "Notification call for %s was not completed\n", event->owner->name);
839 } else {
840 struct ast_channel *answered;
841
842 answered = ast_dial_answered_steal(dial);
843 if (ast_strlen_zero(event->owner->notify_app)) {
844 ast_channel_context_set(answered, event->owner->notify_context);
845 ast_channel_exten_set(answered, event->owner->notify_extension);
846 ast_channel_priority_set(answered, 1);
847 ast_pbx_run(answered);
848 }
849 }
850
851notify_cleanup:
852 if (apptext) {
853 ast_free(apptext);
854 }
855 if (tmpstr) {
856 ast_free(tmpstr);
857 }
858 if (dial) {
859 ast_dial_destroy(dial);
860 }
861 if (chan) {
863 }
864
866
867 return NULL;
868}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_DOWN
Definition: channelstate.h:36
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
@ AST_DIAL_RESULT_ANSWERED
Definition: dial.h:61
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:280
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:223
void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout)
Set the maximum time (globally) allowed for trying to ring phones.
Definition: dial.c:1284
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
Definition: dial.c:935
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:989
@ AST_DIAL_OPTION_ANSWER_EXEC
Definition: dial.h:44
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
Enables an option globally.
Definition: dial.c:1145
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4755
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
static const struct ast_channel_tech null_tech
Definition: res_calendar.c:737
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
Main Channel structure associated with a channel.
Main dialing structure. Contains global options, channels being dialed, and more!
Definition: dial.c:48
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54

References ao2_ref, ast_calendar_unref_event(), ast_channel_alloc, ast_channel_context_set(), ast_channel_datastore_add(), ast_channel_exten_set(), ast_channel_lock, ast_channel_nativeformats_set(), ast_channel_priority_set(), ast_channel_release(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_tech_set(), ast_channel_unlock, ast_datastore_alloc, ast_dial_answered_steal(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), AST_DIAL_OPTION_ANSWER_EXEC, ast_dial_option_global_enable(), AST_DIAL_RESULT_ANSWERED, ast_dial_run(), ast_dial_set_global_timeout(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_free, ast_log, ast_pbx_run(), AST_STATE_DOWN, ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strlen_zero(), ast_verb, buf, ast_datastore::data, DATASTORE_INHERIT_FOREVER, event_notification_datastore, generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, null_tech, pbx_builtin_setvar_helper(), and ast_variable::value.

Referenced by calendar_event_notify().

◆ do_refresh()

static void * do_refresh ( void *  data)
static

Definition at line 1844 of file res_calendar.c.

1845{
1846 for (;;) {
1847 struct timeval now = ast_tvnow();
1848 struct timespec ts = {0,};
1849 int wait;
1850
1852
1853 while (!module_unloading) {
1854 if ((wait = ast_sched_wait(sched)) < 0) {
1855 wait = 1000;
1856 }
1857
1858 ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
1859 if (ast_cond_timedwait(&refresh_condition, &refreshlock, &ts) == ETIMEDOUT) {
1860 break;
1861 }
1862 }
1864
1865 if (module_unloading) {
1866 break;
1867 }
1869 }
1870
1871 return NULL;
1872}
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
static ast_mutex_t refreshlock
Definition: res_calendar.c:227
static ast_cond_t refresh_condition
Definition: res_calendar.c:228
static int module_unloading
Definition: res_calendar.c:230
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:786
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:433

References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_sched_runq(), ast_sched_wait(), ast_tvnow(), module_unloading, NULL, refresh_condition, and refreshlock.

Referenced by load_module().

◆ epoch_to_string()

static char * epoch_to_string ( char *  buf,
size_t  buflen,
time_t  epoch 
)
static

Definition at line 1594 of file res_calendar.c.

1595{
1596 struct ast_tm tm;
1597 struct timeval tv = {
1598 .tv_sec = epoch,
1599 };
1600
1601 if (!epoch) {
1602 *buf = '\0';
1603 return buf;
1604 }
1605 ast_localtime(&tv, &tm, NULL);
1606 ast_strftime(buf, buflen, "%F %r %z", &tm);
1607
1608 return buf;
1609}
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524

References ast_localtime(), ast_strftime(), buf, and NULL.

Referenced by handle_show_calendar().

◆ event_cmp_fn()

static int event_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 309 of file res_calendar.c.

310{
311 const struct ast_calendar_event *one = obj, *two = arg;
312 return !strcmp(one->uid, two->uid) ? CMP_MATCH | CMP_STOP : 0;
313}

References CMP_MATCH, CMP_STOP, and ast_calendar_event::uid.

Referenced by ast_calendar_event_container_alloc(), and build_calendar().

◆ event_hash_fn()

static int event_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 303 of file res_calendar.c.

304{
305 const struct ast_calendar_event *event = obj;
306 return ast_str_hash(event->uid);
307}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_str_hash().

Referenced by ast_calendar_event_container_alloc(), and build_calendar().

◆ event_notification_destroy()

static void event_notification_destroy ( void *  data)
static

Definition at line 697 of file res_calendar.c.

698{
699 struct ast_calendar_event *event = data;
700
702
703}

References ast_calendar_unref_event().

◆ event_notification_duplicate()

static void * event_notification_duplicate ( void *  data)
static

Definition at line 705 of file res_calendar.c.

706{
707 struct ast_calendar_event *event = data;
708
709 if (!event) {
710 return NULL;
711 }
712
713 ao2_ref(event, +1);
714
715 return event;
716}

References ao2_ref, and NULL.

◆ eventlist_destroy()

static void eventlist_destroy ( void *  data)
static

Definition at line 1200 of file res_calendar.c.

1201{
1202 struct eventlist *events = data;
1203
1204 ao2_ref(events, -1);
1205}

References ao2_ref, and events.

◆ eventlist_destructor()

static void eventlist_destructor ( void *  obj)
static

Definition at line 349 of file res_calendar.c.

350{
351 struct eventlist *events = obj;
352 struct evententry *entry;
353
354 while ((entry = AST_LIST_REMOVE_HEAD(events, list))) {
355 ao2_ref(entry->event, -1);
357 }
358}

References ao2_ref, ast_free, AST_LIST_REMOVE_HEAD, events, and evententry::list.

Referenced by calendar_query_exec().

◆ eventlist_duplicate()

static void * eventlist_duplicate ( void *  data)
static

Definition at line 1207 of file res_calendar.c.

1208{
1209 struct eventlist *events = data;
1210
1211 if (!events) {
1212 return NULL;
1213 }
1214
1215 ao2_ref(events, +1);
1216
1217 return events;
1218}

References ao2_ref, events, and NULL.

◆ find_calendar()

static struct ast_calendar * find_calendar ( const char *  name)
static

Definition at line 295 of file res_calendar.c.

296{
297 struct ast_calendar tmp = {
298 .name = name,
299 };
301}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, calendars, name, OBJ_POINTER, and tmp().

Referenced by build_calendar(), calendar_busy_exec(), calendar_query_exec(), calendar_write_exec(), calendarstate(), and handle_show_calendar().

◆ find_event()

static struct ast_calendar_event * find_event ( struct ao2_container events,
const char *  uid 
)
static

Definition at line 315 of file res_calendar.c.

316{
317 struct ast_calendar_event tmp = {
318 .uid = uid,
319 };
320 return ao2_find(events, &tmp, OBJ_POINTER);
321}

References ao2_find, events, OBJ_POINTER, tmp(), and ast_calendar_event::uid.

Referenced by merge_events_cb().

◆ generate_random_string()

static char * generate_random_string ( char *  buf,
size_t  size 
)
static

Generate 32 byte random string (stolen from chan_sip.c)

Definition at line 719 of file res_calendar.c.

720{
721 unsigned long val[4];
722 int x;
723
724 for (x = 0; x < 4; x++) {
725 val[x] = ast_random();
726 }
727 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
728
729 return buf;
730}
Definition: ast_expr2.c:325
long int ast_random(void)
Definition: utils.c:2312

References ast_random(), and buf.

Referenced by calendar_query_exec(), do_notify(), and rtp_allocate_transport().

◆ handle_dump_sched()

static char * handle_dump_sched ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1713 of file res_calendar.c.

1714{
1715 switch(cmd) {
1716 case CLI_INIT:
1717 e->command = "calendar dump sched";
1718 e->usage =
1719 "Usage: calendar dump sched\n"
1720 " Dump the calendar sched context";
1721 return NULL;
1722
1723 case CLI_GENERATE:
1724 return NULL;
1725 }
1726
1728
1729 return CLI_SUCCESS;
1730}
#define CLI_SUCCESS
Definition: cli.h:44
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
void ast_sched_dump(struct ast_sched_context *con)
Dumps the scheduler contents.
Definition: sched.c:743
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

References ast_sched_dump(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

◆ handle_show_calendar()

static char * handle_show_calendar ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1626 of file res_calendar.c.

1627{
1628#define FORMAT "%-18.18s : %-20.20s\n"
1629#define FORMAT2 "%-12.12s: %-40.60s\n"
1630 struct ao2_iterator i;
1631 struct ast_calendar *cal;
1632 struct ast_calendar_event *event;
1633 int which = 0;
1634 char *ret = NULL;
1635
1636 switch(cmd) {
1637 case CLI_INIT:
1638 e->command = "calendar show calendar";
1639 e->usage =
1640 "Usage: calendar show calendar <calendar name>\n"
1641 " Displays information about a calendar\n";
1642 return NULL;
1643
1644 case CLI_GENERATE:
1645 if (a->pos != 3) {
1646 return NULL;
1647 }
1649 while ((cal = ao2_iterator_next(&i))) {
1650 if (!strncasecmp(a->word, cal->name, strlen(a->word)) && ++which > a->n) {
1651 ret = ast_strdup(cal->name);
1652 cal = unref_calendar(cal);
1653 break;
1654 }
1655 cal = unref_calendar(cal);
1656 }
1658 return ret;
1659 }
1660
1661 if (a->argc != 4) {
1662 return CLI_SHOWUSAGE;
1663 }
1664
1665 if (!(cal = find_calendar(a->argv[3]))) {
1666 return NULL;
1667 }
1668
1669 ast_cli(a->fd, FORMAT, "Name", cal->name);
1670 ast_cli(a->fd, FORMAT, "Notify channel", cal->notify_channel);
1671 ast_cli(a->fd, FORMAT, "Notify context", cal->notify_context);
1672 ast_cli(a->fd, FORMAT, "Notify extension", cal->notify_extension);
1673 ast_cli(a->fd, FORMAT, "Notify application", cal->notify_app);
1674 ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata);
1675 ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh);
1676 ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe);
1677
1678 if (cal->autoreminder) {
1679 ast_cli(a->fd, "%-17.17s : %d minutes before event\n", "Autoreminder", cal->autoreminder);
1680 } else {
1681 ast_cli(a->fd, "%-17.17s : None\n", "Autoreminder");
1682 }
1683
1684 ast_cli(a->fd, "%s\n", "Events");
1685 ast_cli(a->fd, "%s\n", "------");
1686
1687 i = ao2_iterator_init(cal->events, 0);
1688 while ((event = ao2_iterator_next(&i))) {
1689 char buf[100];
1690
1691 ast_cli(a->fd, FORMAT2, "Summary", event->summary);
1692 ast_cli(a->fd, FORMAT2, "Description", event->description);
1693 ast_cli(a->fd, FORMAT2, "Organizer", event->organizer);
1694 ast_cli(a->fd, FORMAT2, "Location", event->location);
1695 ast_cli(a->fd, FORMAT2, "Categories", event->categories);
1696 ast_cli(a->fd, "%-12.12s: %d\n", "Priority", event->priority);
1697 ast_cli(a->fd, FORMAT2, "UID", event->uid);
1698 ast_cli(a->fd, FORMAT2, "Start", epoch_to_string(buf, sizeof(buf), event->start));
1699 ast_cli(a->fd, FORMAT2, "End", epoch_to_string(buf, sizeof(buf), event->end));
1700 ast_cli(a->fd, FORMAT2, "Alarm", epoch_to_string(buf, sizeof(buf), event->alarm));
1701 ast_cli(a->fd, FORMAT2, "Busy State", ast_calendar_busy_state_to_str(event->busy_state));
1702 ast_cli(a->fd, "\n");
1703
1705 }
1707 cal = unref_calendar(cal);
1708 return CLI_SUCCESS;
1709#undef FORMAT
1710#undef FORMAT2
1711}
#define CLI_SHOWUSAGE
Definition: cli.h:45
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static char * epoch_to_string(char *buf, size_t buflen, time_t epoch)
static const char * ast_calendar_busy_state_to_str(enum ast_calendar_busy_state busy_state)
#define FORMAT
#define FORMAT2
const ast_string_field notify_context
Definition: calendar.h:129
const ast_string_field notify_app
Definition: calendar.h:129
const ast_string_field notify_extension
Definition: calendar.h:129
const ast_string_field notify_appdata
Definition: calendar.h:129
static struct test_val a

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calendar_busy_state_to_str(), ast_calendar_unref_event(), ast_cli(), ast_strdup, ast_calendar::autoreminder, buf, calendars, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, epoch_to_string(), ast_calendar::events, find_calendar(), FORMAT, FORMAT2, ast_calendar::name, ast_calendar::notify_app, ast_calendar::notify_appdata, ast_calendar::notify_channel, ast_calendar::notify_context, ast_calendar::notify_extension, NULL, ast_calendar::refresh, ast_calendar::timeframe, unref_calendar(), and ast_cli_entry::usage.

◆ handle_show_calendars()

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 1535 of file res_calendar.c.

1536{
1537#define FORMAT "%-20.20s %-10.10s %-6.6s\n"
1538 struct ao2_iterator i;
1539 struct ast_calendar *cal;
1540
1541 switch(cmd) {
1542 case CLI_INIT:
1543 e->command = "calendar show calendars";
1544 e->usage =
1545 "Usage: calendar show calendars\n"
1546 " Lists all registered calendars.\n";
1547 return NULL;
1548 case CLI_GENERATE:
1549 return NULL;
1550 }
1551
1552 ast_cli(a->fd, FORMAT, "Calendar", "Type", "Status");
1553 ast_cli(a->fd, FORMAT, "--------", "----", "------");
1555 while ((cal = ao2_iterator_next(&i))) {
1556 ast_cli(a->fd, FORMAT, cal->name, cal->tech->type, calendar_is_busy(cal) ? "busy" : "free");
1557 cal = unref_calendar(cal);
1558 }
1560
1561 return CLI_SUCCESS;
1562#undef FORMAT
1563}

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), calendar_is_busy(), calendars, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, FORMAT, ast_calendar::name, NULL, ast_calendar::tech, ast_calendar_tech::type, unref_calendar(), and ast_cli_entry::usage.

◆ handle_show_calendars_types()

static char * handle_show_calendars_types ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI command to list of all calendars types currently loaded on the backend.

Definition at line 1566 of file res_calendar.c.

1567{
1568#define FORMAT "%-10.10s %-30.30s\n"
1569 struct ast_calendar_tech *iter;
1570
1571
1572 switch(cmd) {
1573 case CLI_INIT:
1574 e->command = "calendar show types";
1575 e->usage =
1576 "Usage: calendar show types\n"
1577 " Lists all registered calendars types.\n";
1578 return NULL;
1579 case CLI_GENERATE:
1580 return NULL;
1581 }
1582
1583 ast_cli(a->fd, FORMAT, "Type", "Description");
1585 AST_LIST_TRAVERSE(&techs, iter, list) {
1586 ast_cli(a->fd, FORMAT, iter->type, iter->description);
1587 }
1589
1590 return CLI_SUCCESS;
1591#undef FORMAT
1592}

References a, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_calendar_tech::description, FORMAT, ast_calendar_tech::list, NULL, ast_calendar_tech::type, and ast_cli_entry::usage.

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 1072 of file res_calendar.c.

1073{
1074 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1075 struct ast_config *tmpcfg;
1076
1077 if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
1078 tmpcfg == CONFIG_STATUS_FILEINVALID) {
1079 ast_log(LOG_ERROR, "Unable to load config calendar.conf\n");
1080 return -1;
1081 }
1082
1083 if (tmpcfg == CONFIG_STATUS_FILEUNCHANGED) {
1084 return 0;
1085 }
1086
1088 if (calendar_config) {
1090 }
1091
1092 calendar_config = tmpcfg;
1094
1095 return 0;
1096}
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
@ CONFIG_FLAG_FILEUNCHANGED
#define ast_rwlock_wrlock(a)
Definition: lock.h:236
static int reload(void)
Structure used to handle boolean flags.
Definition: utils.h:199

References ast_config_destroy(), ast_config_load2(), ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, calendar_config, CONFIG_FLAG_FILEUNCHANGED, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and reload().

Referenced by load_module(), and reload().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 1923 of file res_calendar.c.

1924{
1927 if (!calendars) {
1928 ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
1930 }
1931
1932 if (load_config(0)) {
1933 /* We don't have calendar support enabled */
1935 }
1936
1940
1941 if (!(sched = ast_sched_context_create())) {
1942 ast_log(LOG_ERROR, "Unable to create sched context\n");
1946 }
1947
1949 ast_log(LOG_ERROR, "Unable to start refresh thread--notifications disabled!\n");
1950 }
1951
1958
1960
1962}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:391
#define ast_mutex_init(pmutex)
Definition: lock.h:186
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
static struct ast_custom_function calendar_query_function
static struct ast_custom_function calendar_write_function
static void * do_refresh(void *data)
static struct ast_custom_function calendar_query_result_function
static ast_mutex_t reloadlock
Definition: res_calendar.c:229
static enum ast_device_state calendarstate(const char *data)
Definition: res_calendar.c:383
static struct ast_custom_function calendar_event_function
static struct ast_cli_entry calendar_cli[]
static struct ast_custom_function calendar_busy_function
static int calendar_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:283
static pthread_t refresh_thread
Definition: res_calendar.c:226
static int calendar_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:289
static int load_config(int reload)
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
#define ARRAY_LEN(a)
Definition: utils.h:666

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ARRAY_LEN, ast_cli_register_multiple, ast_cond_init, ast_config_destroy(), ast_custom_function_register, ast_devstate_prov_add(), ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_pthread_create_background, ast_sched_context_create(), CALENDAR_BUCKETS, calendar_busy_function, calendar_cli, calendar_cmp_fn(), calendar_config, calendar_event_function, calendar_hash_fn(), calendar_query_function, calendar_query_result_function, calendar_write_function, calendars, calendarstate(), do_refresh(), load_config(), LOG_ERROR, NULL, refresh_condition, refresh_thread, refreshlock, and reloadlock.

◆ load_tech_calendars()

static int load_tech_calendars ( struct ast_calendar_tech tech)
static

Definition at line 515 of file res_calendar.c.

516{
517 struct ast_calendar *cal;
518 const char *cat = NULL;
519 const char *val;
520
521 if (!calendar_config) {
522 ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
523 return -1;
524 }
525
527 while ((cat = ast_category_browse(calendar_config, cat))) {
528 if (!strcasecmp(cat, "general")) {
529 continue;
530 }
531
532 if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) {
533 continue;
534 }
535
536 /* A serious error occurred loading calendars from this tech and it should be disabled */
537 if (!(cal = build_calendar(calendar_config, cat, tech))) {
540 return -1;
541 }
542
543 cal = unref_calendar(cal);
544 }
545
547
548 return 0;
549}
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
Definition: res_calendar.c:589
static struct ast_calendar * build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech)
Definition: res_calendar.c:402

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, NULL, ast_calendar::tech, ast_calendar_tech::type, and unref_calendar().

Referenced by ast_calendar_register(), and reload().

◆ match_caltech_cb()

static int match_caltech_cb ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 577 of file res_calendar.c.

578{
579 struct ast_calendar *cal = user_data;
580 struct ast_calendar_tech *tech = arg;
581
582 if (cal->tech == tech) {
583 return CMP_MATCH;
584 }
585
586 return 0;
587}

References CMP_MATCH, and ast_calendar::tech.

Referenced by ast_calendar_unregister().

◆ merge_events_cb()

static int merge_events_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1023 of file res_calendar.c.

1024{
1025 struct ast_calendar_event *old_event = obj, *new_event;
1026 struct ao2_container *new_events = arg;
1027
1028 /* If we don't find the old_event in new_events, then we can safely delete the old_event */
1029 if (!(new_event = find_event(new_events, old_event->uid))) {
1030 old_event = destroy_event(old_event);
1031 return CMP_MATCH;
1032 }
1033
1034 /* We have events to merge. If any data that will affect a scheduler event has changed,
1035 * then we need to replace the scheduler event */
1036 schedule_calendar_event(old_event->owner, old_event, new_event);
1037
1038 /* Since we don't want to mess with cancelling sched events and adding new ones, just
1039 * copy the internals of the new_event to the old_event */
1040 copy_event_data(old_event, new_event);
1041
1042 /* Now we can go ahead and unlink the new_event from new_events and unref it so that only completely
1043 * new events remain in the container */
1044 ao2_unlink(new_events, new_event);
1045 new_event = ast_calendar_unref_event(new_event);
1046
1047 return 0;
1048}
static void copy_event_data(struct ast_calendar_event *dst, struct ast_calendar_event *src)
Definition: res_calendar.c:928
static struct ast_calendar_event * find_event(struct ao2_container *events, const char *uid)
Definition: res_calendar.c:315

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().

◆ null_chan_write()

static int null_chan_write ( struct ast_channel chan,
struct ast_frame frame 
)
static

Definition at line 732 of file res_calendar.c.

733{
734 return 0;
735}

◆ reload()

static int reload ( void  )
static

Definition at line 1818 of file res_calendar.c.

1819{
1820 struct ast_calendar_tech *iter;
1821
1823
1824 /* Mark existing calendars for deletion */
1826 load_config(1);
1827
1829 AST_LIST_TRAVERSE(&techs, iter, list) {
1830 if (load_tech_calendars(iter)) {
1831 ast_log(LOG_WARNING, "Failed to reload %s calendars, module disabled\n", iter->type);
1832 }
1833 }
1835
1836 /* Delete calendars that no longer show up in the config */
1838
1840
1841 return 0;
1842}
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)

References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, calendars, cb_pending_deletion(), cb_rm_pending_deletion(), ast_calendar_tech::list, load_config(), load_tech_calendars(), LOG_WARNING, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, reloadlock, and ast_calendar_tech::type.

Referenced by load_config().

◆ schedule_calendar_event()

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 956 of file res_calendar.c.

957{
958 struct timeval now = ast_tvnow();
960 time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end;
961 int changed = 0;
962
963 event = cmp_event ? cmp_event : old_event;
964
966 if (!ast_strlen_zero(cal->notify_channel) && (!cmp_event || old_event->alarm != event->alarm)) {
967 changed = 1;
968 if (cal->autoreminder) {
969 alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000;
970 } else if (event->alarm) {
971 alarm_notify_sched = (event->alarm - now.tv_sec) * 1000;
972 }
973
974 /* For now, send the notification if we missed it, but the meeting hasn't happened yet */
975 if (event->start >= now.tv_sec) {
976 if (alarm_notify_sched <= 0) {
977 alarm_notify_sched = 1;
978 }
980 AST_SCHED_REPLACE(old_event->notify_sched, sched, alarm_notify_sched, calendar_event_notify, old_event);
982 ast_debug(3, "Calendar alarm event notification scheduled to happen in %ld ms\n", (long) alarm_notify_sched);
983 }
984 }
985
986 if (!cmp_event || old_event->start != event->start) {
987 changed = 1;
988 devstate_sched_start = (event->start - now.tv_sec) * 1000;
989
990 if (devstate_sched_start < 1) {
991 devstate_sched_start = 1;
992 }
993
995 AST_SCHED_REPLACE(old_event->bs_start_sched, sched, devstate_sched_start, calendar_devstate_change, old_event);
997 ast_debug(3, "Calendar bs_start event notification scheduled to happen in %ld ms\n", (long) devstate_sched_start);
998 }
999
1000 if (!cmp_event || old_event->end != event->end) {
1001 changed = 1;
1002 devstate_sched_end = (event->end - now.tv_sec) * 1000;
1003
1004 if (devstate_sched_end <= 0) { /* if we let this slip by, Asterisk will assert */
1005 ast_log(LOG_WARNING, "Whoops! Event end notification scheduled in the past: %ld ms\n", (long) devstate_sched_end);
1006 } else {
1008 AST_SCHED_REPLACE(old_event->bs_end_sched, sched, devstate_sched_end, calendar_devstate_change, old_event);
1010 ast_debug(3, "Calendar bs_end event notification scheduled to happen in %ld ms\n", (long) devstate_sched_end);
1011 }
1012 }
1013
1014 if (changed) {
1016 }
1017
1019
1020 return 0;
1021}
static int calendar_event_notify(const void *data)
Definition: res_calendar.c:870
static int calendar_devstate_change(const void *data)
Definition: res_calendar.c:894
#define AST_SCHED_REPLACE(id, sched, when, callback, data)
Definition: sched.h:127

References ast_calendar_event::alarm, ao2_lock, ao2_unlock, ast_cond_signal, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_SCHED_REPLACE, ast_strlen_zero(), 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, LOG_WARNING, ast_calendar::notify_channel, ast_calendar_event::notify_sched, refresh_condition, refreshlock, and ast_calendar_event::start.

Referenced by add_new_event_cb(), and merge_events_cb().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1875 of file res_calendar.c.

1876{
1877 struct ast_calendar_tech *tech;
1878
1879 ast_devstate_prov_del("calendar");
1886
1887 /* Remove all calendars */
1890 calendars = NULL;
1891
1893 module_unloading = 1;
1896 pthread_join(refresh_thread, NULL);
1897
1899
1902 ast_unload_resource(tech->module, 0);
1903 }
1906
1909
1910 return 0;
1911}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1219
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:271
const char * module
Definition: calendar.h:74

References ao2_callback, ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), ast_cond_signal, ast_config_destroy(), ast_custom_function_unregister(), ast_devstate_prov_del(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_sched_context_destroy(), ast_unload_resource(), calendar_busy_function, calendar_cli, calendar_config, calendar_event_function, calendar_query_function, calendar_query_result_function, calendar_write_function, calendars, ast_calendar_tech::list, ast_calendar_tech::module, module_unloading, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, refresh_condition, refresh_thread, and refreshlock.

◆ unref_calendar()

static struct ast_calendar * unref_calendar ( struct ast_calendar cal)
static

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Calendar integration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
static

Definition at line 1969 of file res_calendar.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1969 of file res_calendar.c.

◆ calendar_busy_function

struct ast_custom_function calendar_busy_function
static
Initial value:
= {
.name = "CALENDAR_BUSY",
}
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.

Definition at line 1121 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendar_cli

struct ast_cli_entry calendar_cli[]
static

Definition at line 1732 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendar_config

struct ast_config* calendar_config
static

◆ calendar_event_function

struct ast_custom_function calendar_event_function
static
Initial value:
= {
.name = "CALENDAR_EVENT",
}
static int calendar_event_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1797 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendar_query_function

struct ast_custom_function calendar_query_function
static
Initial value:
= {
.name = "CALENDAR_QUERY",
}
static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1306 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendar_query_result_function

struct ast_custom_function calendar_query_result_function
static
Initial value:
= {
.name = "CALENDAR_QUERY_RESULT",
}
static int calendar_query_result_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1417 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendar_write_function

struct ast_custom_function calendar_write_function
static
Initial value:
= {
.name = "CALENDAR_WRITE",
}
static int calendar_write_exec(struct ast_channel *chan, const char *cmd, char *data, const char *value)

Definition at line 1529 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendars

struct ao2_container* calendars
static

◆ config_lock

ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
static

◆ event_notification_datastore

const struct ast_datastore_info event_notification_datastore
static
Initial value:
= {
.type = "EventNotification",
}
static void * event_notification_duplicate(void *data)
Definition: res_calendar.c:705
static void event_notification_destroy(void *data)
Definition: res_calendar.c:697

Definition at line 237 of file res_calendar.c.

Referenced by calendar_event_read(), and do_notify().

◆ eventlist_datastore_info

const struct ast_datastore_info eventlist_datastore_info
static
Initial value:
= {
.type = "CalendarEventList",
.destroy = eventlist_destroy,
.duplicate = eventlist_duplicate,
}
static void * eventlist_duplicate(void *data)
static void eventlist_destroy(void *data)

Definition at line 243 of file res_calendar.c.

Referenced by calendar_query_exec(), and calendar_query_result_exec().

◆ module_unloading

int module_unloading
static

Definition at line 230 of file res_calendar.c.

Referenced by do_refresh(), and unload_module().

◆ null_tech

const struct ast_channel_tech null_tech
static
Initial value:
= {
.type = "NULL",
.description = "Null channel (should not see this)",
.write = null_chan_write,
}
static int null_chan_write(struct ast_channel *chan, struct ast_frame *frame)
Definition: res_calendar.c:732

Definition at line 737 of file res_calendar.c.

Referenced by do_notify().

◆ refresh_condition

ast_cond_t refresh_condition
static

Definition at line 228 of file res_calendar.c.

Referenced by do_refresh(), load_module(), schedule_calendar_event(), and unload_module().

◆ refresh_thread

pthread_t refresh_thread = AST_PTHREADT_NULL
static

Definition at line 226 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ refreshlock

ast_mutex_t refreshlock
static

◆ reloadlock

ast_mutex_t reloadlock
static

Definition at line 229 of file res_calendar.c.

Referenced by load_module(), and reload().

◆ sched

struct ast_sched_context* sched
static

Definition at line 225 of file res_calendar.c.

◆ techs

struct techs techs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static