Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 237 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 1984 of file res_calendar.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1984 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 1141 of file res_calendar.c.

1142{
1143 struct evententry *entry, *iter;
1144 long event_startdiff = labs(start - event->start);
1145 long event_enddiff = labs(end - event->end);
1146 int i = 0;
1147
1148 if (!(entry = ast_calloc(1, sizeof(*entry)))) {
1149 ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1150 return -1;
1151 }
1152
1153 entry->event = event;
1154 ao2_ref(event, +1);
1155
1156 if (start == end) {
1158 long startdiff = labs(iter->event->start - start);
1159
1160 ast_debug(10, "Comparing %s with startdiff %ld to %s with startdiff %ld\n", event->summary, event_startdiff, iter->event->summary, startdiff);
1161 ++i;
1162 if (startdiff > event_startdiff) {
1164 return i;
1165 }
1166 if (startdiff == event_startdiff) {
1167 long enddiff = labs(iter->event->end - end);
1168
1169 if (enddiff > event_enddiff) {
1171 return i;
1172 }
1173 if (event_startdiff == enddiff) {
1174 if (strcmp(event->uid, iter->event->uid) < 0) {
1176 return i;
1177 }
1178 }
1179 }
1180 }
1182
1184
1185 return i;
1186 }
1187
1189 ++i;
1190 if (iter->event->start > event->start) {
1192 return i;
1193 }
1194
1195 if (iter->event->start == event->start) {
1196 if ((iter->event->end - iter->event->start) == (event->end - event->start)) {
1197 if (strcmp(event->uid, iter->event->uid) < 0) {
1199 return i;
1200 }
1201 }
1202 if ((iter->event->end - iter->event->start) < (event->end - event->start)) {
1204 return i;
1205 }
1206 }
1207 }
1209
1211
1212 return i;
1213}
static const struct adsi_event events[]
Definition: app_adsiprog.c:88
#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: astman.c:222
struct evententry::@426 list
struct ast_calendar_event * event
Definition: res_calendar.c:265

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

1066{
1067 struct ast_calendar_event *new_event = obj;
1068 struct ao2_container *events = arg;
1069
1070 ao2_link(events, new_event);
1071 schedule_calendar_event(new_event->owner, new_event, NULL);
1072 return CMP_MATCH;
1073}
#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:971
#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 1626 of file res_calendar.c.

1627{
1628 switch (busy_state) {
1630 return "Free";
1632 return "Busy (Tentative)";
1634 return "Busy";
1635 default:
1636 return "Unknown (Busy)";
1637 }
1638}
@ 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 677 of file res_calendar.c.

678{
679 ast_debug(3, "Clearing all events for calendar %s\n", cal->name);
680
682}
#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:668
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 275 of file res_calendar.c.

276{
278
279 if (!calendar_config) {
281 return NULL;
282 }
283
284 return calendar_config;
285}
#define ast_rwlock_rdlock(a)
Definition: lock.h:242
#define ast_rwlock_unlock(a)
Definition: lock.h:241
static struct ast_config * calendar_config
Definition: res_calendar.c:272
static ast_rwlock_t config_lock
Definition: res_calendar.c:273

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

288{
290}

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

685{
687 if (!(event = ao2_alloc(sizeof(*event), calendar_event_destructor))) {
688 return NULL;
689 }
690
691 if (ast_string_field_init(event, 32)) {
693 return NULL;
694 }
695
696 event->owner = cal;
697 event->notify_sched = -1;
698 event->bs_start_sched = -1;
699 event->bs_end_sched = -1;
700
701 AST_LIST_HEAD_INIT_NOLOCK(&event->attendees);
702
703 return event;
704}
#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:338
static void calendar_event_destructor(void *obj)
Definition: res_calendar.c:626
#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 706 of file res_calendar.c.

707{
710}
@ 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:318
#define CALENDAR_BUCKETS
Definition: res_calendar.c:237
static int event_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:324

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

1076{
1077 /* Loop through all events attached to the calendar. If there is a matching new event
1078 * merge its data over and handle any schedule changes that need to be made. Then remove
1079 * the new_event from new_events so that we are left with only new_events that we can add later. */
1081
1082 /* Now, we should only have completely new events in new_events. Loop through and add them */
1084}
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 566 of file res_calendar.c.

567{
568 struct ast_calendar_tech *iter;
569
570 if (!calendar_config) {
571 ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
572 return -1;
573 }
574
576 AST_LIST_TRAVERSE(&techs, iter, list) {
577 if(!strcasecmp(tech->type, iter->type)) {
578 ast_log(LOG_WARNING, "Already have a handler for calendar type '%s'\n", tech->type);
580 return -1;
581 }
582 }
586
587 ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description);
588
589 return load_tech_calendars(tech);
590}
#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:440
static int load_tech_calendars(struct ast_calendar_tech *tech)
Definition: res_calendar.c:530
Individual calendaring technology data.
Definition: calendar.h:71
struct ast_calendar_tech::@203 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 604 of file res_calendar.c.

605{
606 struct ast_calendar_tech *iter;
607
610 if (iter != tech) {
611 continue;
612 }
613
615
618 ast_verb(2, "Unregistered calendar type '%s'\n", tech->type);
619 break;
620 }
623
624}
#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:441
static int match_caltech_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:592
static struct ao2_container * calendars
Definition: res_calendar.c:239

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

418{
419 struct ast_calendar *cal;
420 struct ast_variable *v, *last = NULL;
421 int new_calendar = 0;
422
423 cal = find_calendar(cat);
424 if (cal && cal->fetch_again_at_reload) {
425 /** Create new calendar, old will be removed during reload */
426 cal = unref_calendar(cal);
427 }
428 if (!cal) {
429 new_calendar = 1;
430 if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) {
431 ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n");
432 return NULL;
433 }
434
437 if (!cal->events) {
438 ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat);
439 cal = unref_calendar(cal);
440 return NULL;
441 }
442
443 if (ast_string_field_init(cal, 32)) {
444 ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat);
445 cal = unref_calendar(cal);
446 return NULL;
447 }
448 } else {
449 cal->pending_deletion = 0;
450 }
451
452 ast_string_field_set(cal, name, cat);
453 cal->tech = tech;
454
455 cal->refresh = 3600;
456 cal->timeframe = 60;
457 cal->notify_waittime = 30000;
458 cal->fetch_again_at_reload = 0;
459
460 for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
461 if (!strcasecmp(v->name, "autoreminder")) {
462 cal->autoreminder = atoi(v->value);
463 } else if (!strcasecmp(v->name, "channel")) {
465 } else if (!strcasecmp(v->name, "context")) {
466 ast_string_field_set(cal, notify_context, v->value);
467 } else if (!strcasecmp(v->name, "extension")) {
468 ast_string_field_set(cal, notify_extension, v->value);
469 } else if (!strcasecmp(v->name, "waittime")) {
470 int i = atoi(v->value);
471 if (i > 0) {
472 cal->notify_waittime = 1000 * i;
473 }
474 } else if (!strcasecmp(v->name, "app")) {
475 ast_string_field_set(cal, notify_app, v->value);
476 } else if (!strcasecmp(v->name, "appdata")) {
477 ast_string_field_set(cal, notify_appdata, v->value);
478 } else if (!strcasecmp(v->name, "refresh")) {
479 cal->refresh = atoi(v->value);
480 } else if (!strcasecmp(v->name, "fetch_again_at_reload")) {
482 } else if (!strcasecmp(v->name, "timeframe")) {
483 cal->timeframe = atoi(v->value);
484 } else if (!strcasecmp(v->name, "setvar")) {
485 char *name, *value;
486 struct ast_variable *var;
487
488 if ((name = (value = ast_strdup(v->value)))) {
489 strsep(&value, "=");
490 if (value) {
492 if (last) {
493 last->next = var;
494 } else {
495 cal->vars = var;
496 }
497 last = var;
498 }
499 } else {
500 ast_log(LOG_WARNING, "Malformed argument. Should be '%s: variable=value'\n", v->name);
501 }
502 ast_free(name);
503 }
504 }
505 }
506
507 if (cal->autoreminder && ast_strlen_zero(cal->notify_channel)) {
509 "You have set 'autoreminder' but not 'channel' for calendar '%s.' "
510 "Notifications will not occur.\n",
511 cal->name);
512 }
513
514 if (new_calendar) {
516 ast_cond_init(&cal->unload, NULL);
517 ao2_link(calendars, cal);
518 if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) {
519 /* If we start failing to create threads, go ahead and return NULL
520 * and the tech module will be unregistered
521 */
522 ao2_unlink(calendars, cal);
523 cal = unref_calendar(cal);
524 }
525 }
526
527 return cal;
528}
struct sla_ringing_trunk * last
Definition: app_sla.c:338
#define var
Definition: ast_expr2f.c:605
char * strsep(char **str, const char *delims)
#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
#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:73
#define ast_cond_init(cond, attr)
Definition: lock.h:208
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:292
static void calendar_destructor(void *obj)
Definition: res_calendar.c:344
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:310
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:314
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 375 of file res_calendar.c.

376{
377 struct ast_calendar_event *event = obj;
378 int *is_busy = arg;
379 struct timeval tv = ast_tvnow();
380
381 if (tv.tv_sec >= event->start && tv.tv_sec <= event->end && event->busy_state > AST_CALENDAR_BS_FREE) {
382 *is_busy = 1;
383 return CMP_STOP;
384 }
385
386 return 0;
387}
@ 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 1114 of file res_calendar.c.

1115{
1116 struct ast_calendar *cal;
1117
1118 if (ast_strlen_zero(data)) {
1119 ast_log(LOG_WARNING, "CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n");
1120 return -1;
1121 }
1122
1123 cal = find_calendar(data);
1124
1125 if (!cal) {
1126 ast_log(LOG_WARNING, "Could not find calendar '%s'\n", data);
1127 return -1;
1128 }
1129
1130 strcpy(buf, calendar_is_busy(cal) ? "1" : "0");
1131 cal = unref_calendar(cal);
1132
1133 return 0;
1134}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:389

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

305{
306 const struct ast_calendar *one = obj, *two = arg;
307 return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP: 0;
308}

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

345{
346 struct ast_calendar *cal = obj;
347
348 ast_debug(3, "Destroying calendar %s\n", cal->name);
349
350 ao2_lock(cal);
351 cal->unloading = 1;
352 ast_cond_signal(&cal->unload);
353 pthread_join(cal->thread, NULL);
354 if (cal->tech_pvt) {
355 cal->tech_pvt = cal->tech->unref_calendar(cal->tech_pvt);
356 }
360 ao2_ref(cal->events, -1);
361 ao2_unlock(cal);
362}
#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:210
void ast_calendar_clear_events(struct ast_calendar *cal)
Remove all events from calendar.
Definition: res_calendar.c:677
#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 909 of file res_calendar.c.

910{
911 struct ast_calendar_event *event = (struct ast_calendar_event *)data;
912 struct timeval now = ast_tvnow();
913 int is_end_event;
914
915 if (!event) {
916 ast_log(LOG_WARNING, "Event was NULL!\n");
917 return 0;
918 }
919
920 ao2_ref(event, +1);
921
922 is_end_event = event->end <= now.tv_sec;
923
924 if (is_end_event) {
925 event->bs_end_sched = -1;
926 } else {
927 event->bs_start_sched = -1;
928 }
929
930 /* We can have overlapping events, so ignore the event->busy_state and check busy state
931 * based on all events in the calendar */
932 if (!calendar_is_busy(event->owner)) {
934 } else {
936 }
937
939
940 return 0;
941}
@ 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:513
@ 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 626 of file res_calendar.c.

627{
628 struct ast_calendar_event *event = obj;
629 struct ast_calendar_attendee *attendee;
630
631 ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name);
633 while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) {
634 if (attendee->data) {
635 ast_free(attendee->data);
636 }
637 ast_free(attendee);
638 }
639}
#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 885 of file res_calendar.c.

886{
887 struct ast_calendar_event *event = (void *)data;
888 int res = -1;
889 pthread_t notify_thread = AST_PTHREADT_NULL;
890
891 if (!(event && event->owner)) {
892 ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
893 return res;
894 }
895
896 ao2_ref(event, +1);
897 event->notify_sched = -1;
898
899 if (ast_pthread_create_background(&notify_thread, NULL, do_notify, event) < 0) {
900 ast_log(LOG_ERROR, "Could not create notification thread\n");
901 return res;
902 }
903
904 res = 0;
905
906 return res;
907}
static void * do_notify(void *data)
Definition: res_calendar.c:758
#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 1754 of file res_calendar.c.

1755{
1756 struct ast_datastore *datastore;
1757 struct ast_calendar_event *event;
1758
1759 if (!chan) {
1760 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1761 return -1;
1762 }
1763
1764 if (ast_strlen_zero(data)) {
1765 ast_log(LOG_WARNING, "%s requires an argument\n", cmd);
1766 return -1;
1767 }
1768
1769 ast_channel_lock(chan);
1770 if (!(datastore = ast_channel_datastore_find(chan, &event_notification_datastore, NULL))) {
1771 ast_log(LOG_WARNING, "There is no event notification datastore on '%s'!\n", ast_channel_name(chan));
1772 ast_channel_unlock(chan);
1773 return -1;
1774 }
1775 ast_channel_unlock(chan);
1776
1777 if (!(event = datastore->data)) {
1778 ast_log(LOG_WARNING, "The datastore contains no data!\n");
1779 return -1;
1780 }
1781
1782 if (!strcasecmp(data, "summary")) {
1783 ast_copy_string(buf, event->summary, len);
1784 } else if (!strcasecmp(data, "description")) {
1785 ast_copy_string(buf, event->description, len);
1786 } else if (!strcasecmp(data, "organizer")) {
1787 ast_copy_string(buf, event->organizer, len);
1788 } else if (!strcasecmp(data, "location")) {
1789 ast_copy_string(buf, event->location, len);
1790 } else if (!strcasecmp(data, "categories")) {
1791 ast_copy_string(buf, event->categories, len);
1792 } else if (!strcasecmp(data, "priority")) {
1793 snprintf(buf, len, "%d", event->priority);
1794 } else if (!strcasecmp(data, "calendar")) {
1795 ast_copy_string(buf, event->owner->name, len);
1796 } else if (!strcasecmp(data, "uid")) {
1797 ast_copy_string(buf, event->uid, len);
1798 } else if (!strcasecmp(data, "start")) {
1799 snprintf(buf, len, "%ld", (long)event->start);
1800 } else if (!strcasecmp(data, "end")) {
1801 snprintf(buf, len, "%ld", (long)event->end);
1802 } else if (!strcasecmp(data, "busystate")) {
1803 snprintf(buf, len, "%u", event->busy_state);
1804 } else if (!strcasecmp(data, "attendees")) {
1806 }
1807
1808
1809 return 0;
1810}
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2972
#define ast_channel_unlock(chan)
Definition: channel.h:2973
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:2368
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:252
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 298 of file res_calendar.c.

299{
300 const struct ast_calendar *cal = obj;
301 return ast_str_case_hash(cal->name);
302}
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 389 of file res_calendar.c.

390{
391 int is_busy = 0;
392
394
395 return is_busy;
396}
static int calendar_busy_callback(void *obj, void *arg, int flags)
Definition: res_calendar.c:375

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

1327{
1328 struct ast_str *tmp;
1329 struct ast_calendar_attendee *attendee;
1330
1331 if (!(tmp = ast_str_create(32))) {
1332 ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n");
1333 return;
1334 }
1335
1336 AST_LIST_TRAVERSE(&event->attendees, attendee, next) {
1337 ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data);
1338 }
1339
1341 ast_free(tmp);
1342}
#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, and ast_calendar_attendee::next.

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

1236{
1237 struct ast_calendar *cal;
1238 struct ao2_iterator i;
1239 struct ast_calendar_event *event;
1240 struct eventlist *events;
1241 time_t start = INT_MIN, end = INT_MAX;
1242 struct ast_datastore *eventlist_datastore;
1244 AST_APP_ARG(calendar);
1245 AST_APP_ARG(start);
1247 );
1248
1249 if (!chan) {
1250 ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd);
1251 return -1;
1252 }
1253
1255
1256 if (ast_strlen_zero(args.calendar)) {
1257 ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd);
1258 return -1;
1259 }
1260
1261 if (!(cal = find_calendar(args.calendar))) {
1262 ast_log(LOG_WARNING, "Unknown calendar '%s'\n", args.calendar);
1263 return -1;
1264 }
1265
1266 if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) {
1267 ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1268 cal = unref_calendar(cal);
1269 return -1;
1270 }
1271
1272 if (!ast_strlen_zero(args.start)) {
1273 start = atoi(args.start);
1274 }
1275
1276 if (!ast_strlen_zero(args.end)) {
1277 end = atoi(args.end);
1278 }
1279
1280 i = ao2_iterator_init(cal->events, 0);
1281 while ((event = ao2_iterator_next(&i))) {
1282 if (!(start > event->end || end < event->start)) {
1283 ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end);
1284 if (add_event_to_list(events, event, start, end) < 0) {
1286 cal = unref_calendar(cal);
1287 ao2_ref(events, -1);
1289 return -1;
1290 }
1291 }
1292
1294 }
1296
1297 ast_channel_lock(chan);
1298 do {
1301 ast_channel_unlock(chan);
1302
1303 if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) {
1304 ast_log(LOG_ERROR, "Could not allocate datastore!\n");
1305 cal = unref_calendar(cal);
1306 ao2_ref(events, -1);
1307 return -1;
1308 }
1309
1310 eventlist_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1311 eventlist_datastore->data = events;
1312
1313 ast_channel_lock(chan);
1314 ast_channel_datastore_add(chan, eventlist_datastore);
1315 ast_channel_unlock(chan);
1316
1317 cal = unref_calendar(cal);
1318 return 0;
1319}
#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:2354
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:194
#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:364
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:734
static const struct ast_datastore_info eventlist_datastore_info
Definition: res_calendar.c:258
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 1344 of file res_calendar.c.

1345{
1346 struct ast_datastore *datastore;
1347 struct eventlist *events;
1348 struct evententry *entry;
1349 int row = 1;
1350 size_t listlen = 0;
1352 AST_APP_ARG(id);
1353 AST_APP_ARG(field);
1354 AST_APP_ARG(row);
1355 );
1356
1357 if (!chan) {
1358 ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
1359 return -1;
1360 }
1361
1363
1364 if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) {
1365 ast_log(LOG_WARNING, "%s requires an id and a field", cmd);
1366 return -1;
1367 }
1368
1369 ast_channel_lock(chan);
1370 if (!(datastore = ast_channel_datastore_find(chan, &eventlist_datastore_info, args.id))) {
1371 ast_log(LOG_WARNING, "There is no event notification datastore with id '%s' on '%s'!\n", args.id, ast_channel_name(chan));
1372 ast_channel_unlock(chan);
1373 return -1;
1374 }
1375 ast_channel_unlock(chan);
1376
1377 if (!(events = datastore->data)) {
1378 ast_log(LOG_WARNING, "The datastore contains no data!\n");
1379 return -1;
1380 }
1381
1382 if (!ast_strlen_zero(args.row)) {
1383 row = atoi(args.row);
1384 }
1385
1386 AST_LIST_TRAVERSE(events, entry, list) {
1387 listlen++;
1388 }
1389
1390 if (!strcasecmp(args.field, "getnum")) {
1391 snprintf(buf, len, "%zu", listlen);
1392 return 0;
1393 }
1394
1395 AST_LIST_TRAVERSE(events, entry, list) {
1396 if (--row) {
1397 continue;
1398 }
1399 if (!strcasecmp(args.field, "summary")) {
1400 ast_copy_string(buf, entry->event->summary, len);
1401 } else if (!strcasecmp(args.field, "description")) {
1403 } else if (!strcasecmp(args.field, "organizer")) {
1405 } else if (!strcasecmp(args.field, "location")) {
1407 } else if (!strcasecmp(args.field, "categories")) {
1409 } else if (!strcasecmp(args.field, "priority")) {
1410 snprintf(buf, len, "%d", entry->event->priority);
1411 } else if (!strcasecmp(args.field, "calendar")) {
1412 ast_copy_string(buf, entry->event->owner->name, len);
1413 } else if (!strcasecmp(args.field, "uid")) {
1414 ast_copy_string(buf, entry->event->uid, len);
1415 } else if (!strcasecmp(args.field, "start")) {
1416 snprintf(buf, len, "%ld", (long) entry->event->start);
1417 } else if (!strcasecmp(args.field, "end")) {
1418 snprintf(buf, len, "%ld", (long) entry->event->end);
1419 } else if (!strcasecmp(args.field, "busystate")) {
1420 snprintf(buf, len, "%u", entry->event->busy_state);
1421 } else if (!strcasecmp(args.field, "attendees")) {
1423 } else {
1424 ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field);
1425 }
1426 break;
1427 }
1428
1429 return 0;
1430}
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

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, ast_calendar_event::busy_state, calendar_join_attendees(), ast_calendar_event::categories, ast_datastore::data, ast_calendar_event::description, ast_calendar_event::end, evententry::event, eventlist_datastore_info, events, len(), evententry::list, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.

◆ calendar_write_exec()

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

Definition at line 1437 of file res_calendar.c.

1438{
1439 int i, j, ret = -1;
1440 char *val_dup = NULL;
1441 struct ast_calendar *cal = NULL;
1442 struct ast_calendar_event *event = NULL;
1443 struct timeval tv = ast_tvnow();
1444 AST_DECLARE_APP_ARGS(fields,
1445 AST_APP_ARG(field)[10];
1446 );
1448 AST_APP_ARG(value)[10];
1449 );
1450
1451 if (!(val_dup = ast_strdup(value))) {
1452 ast_log(LOG_ERROR, "Could not allocate memory for values\n");
1453 goto write_cleanup;
1454 }
1455
1456 AST_STANDARD_APP_ARGS(fields, data);
1457 AST_STANDARD_APP_ARGS(values, val_dup);
1458
1459 /* XXX Eventually we will support unnamed calendars, so if we don't find one, we parse
1460 * for a calendar type and create it */
1461 if (!(cal = find_calendar(fields.field[0]))) {
1462 ast_log(LOG_WARNING, "Couldn't find calendar '%s'\n", fields.field[0]);
1463 goto write_cleanup;
1464 }
1465
1466 if (!(cal->tech->write_event)) {
1467 ast_log(LOG_WARNING, "Calendar '%s' has no write function!\n", cal->name);
1468 goto write_cleanup;
1469 }
1470
1471 if (!(event = ast_calendar_event_alloc(cal))) {
1472 goto write_cleanup;
1473 }
1474
1475 if (ast_strlen_zero(fields.field[0])) {
1476 ast_log(LOG_WARNING, "CALENDAR_WRITE requires a calendar name!\n");
1477 goto write_cleanup;
1478 }
1479
1480 if (fields.argc - 1 != values.argc) {
1481 ast_log(LOG_WARNING, "CALENDAR_WRITE should have the same number of fields (%u) and values (%u)!\n", fields.argc - 1, values.argc);
1482 goto write_cleanup;
1483 }
1484
1485 event->owner = cal;
1486
1487 for (i = 1, j = 0; i < fields.argc; i++, j++) {
1488 if (!strcasecmp(fields.field[i], "summary")) {
1489 ast_string_field_set(event, summary, values.value[j]);
1490 } else if (!strcasecmp(fields.field[i], "description")) {
1491 ast_string_field_set(event, description, values.value[j]);
1492 } else if (!strcasecmp(fields.field[i], "organizer")) {
1493 ast_string_field_set(event, organizer, values.value[j]);
1494 } else if (!strcasecmp(fields.field[i], "location")) {
1495 ast_string_field_set(event, location, values.value[j]);
1496 } else if (!strcasecmp(fields.field[i], "categories")) {
1498 } else if (!strcasecmp(fields.field[i], "priority")) {
1499 event->priority = atoi(values.value[j]);
1500 } else if (!strcasecmp(fields.field[i], "uid")) {
1501 ast_string_field_set(event, uid, values.value[j]);
1502 } else if (!strcasecmp(fields.field[i], "start")) {
1503 event->start = atoi(values.value[j]);
1504 } else if (!strcasecmp(fields.field[i], "end")) {
1505 event->end = atoi(values.value[j]);
1506 } else if (!strcasecmp(fields.field[i], "busystate")) {
1507 event->busy_state = atoi(values.value[j]);
1508 } else {
1509 ast_log(LOG_WARNING, "Unknown calendar event field '%s'\n", fields.field[i]);
1510 }
1511 }
1512
1513 if (!event->start) {
1514 event->start = tv.tv_sec;
1515 }
1516
1517 if (!event->end) {
1518 event->end = tv.tv_sec;
1519 }
1520
1521 if((ret = cal->tech->write_event(event))) {
1522 ast_log(LOG_WARNING, "Writing event to calendar '%s' failed!\n", cal->name);
1523 }
1524
1525write_cleanup:
1526 if (ret) {
1527 pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "0");
1528 } else {
1529 pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "1");
1530 }
1531 if (cal) {
1532 cal = unref_calendar(cal);
1533 }
1534 if (event) {
1536 }
1537 if (val_dup) {
1538 ast_free(val_dup);
1539 }
1540
1541 return ret;
1542}
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:684
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 398 of file res_calendar.c.

399{
401 struct ast_calendar *cal;
402
403 if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) {
404 return AST_DEVICE_INVALID;
405 }
406
407 if (cal->tech->is_busy) {
409 } else {
411 }
412
413 cal = unref_calendar(cal);
414 return state;
415}
enum cc_state state
Definition: ccss.c:399
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 1817 of file res_calendar.c.

1818{
1819 struct ast_calendar *cal = user_data;
1820
1821 cal->pending_deletion = 1;
1822
1823 return CMP_MATCH;
1824}

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

1827{
1828 struct ast_calendar *cal = user_data;
1829
1830 return cal->pending_deletion ? CMP_MATCH : 0;
1831}

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

669{
670 struct ast_calendar_event *event = user_data;
671
672 event = destroy_event(event);
673
674 return CMP_MATCH;
675}
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
Definition: res_calendar.c:643

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

944{
945 struct ast_calendar_attendee *attendee;
946
947 ast_string_field_set(dst, summary, src->summary);
948 ast_string_field_set(dst, description, src->description);
949 ast_string_field_set(dst, organizer, src->organizer);
950 ast_string_field_set(dst, location, src->location);
951 ast_string_field_set(dst, uid, src->uid);
953 dst->priority = src->priority;
954 dst->owner = src->owner;
955 dst->start = src->start;
956 dst->end = src->end;
957 dst->alarm = src->alarm;
958 dst->busy_state = src->busy_state;
959
960 /* Delete any existing attendees */
961 while ((attendee = AST_LIST_REMOVE_HEAD(&dst->attendees, next))) {
962 ast_free(attendee);
963 }
964
965 /* Copy over the new attendees */
966 while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) {
967 AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next);
968 }
969}
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 643 of file res_calendar.c.

644{
645 if (event->notify_sched > -1 && ast_sched_del(sched, event->notify_sched)) {
646 ast_debug(3, "Notification running, can't delete sched entry\n");
647 }
648 if (event->bs_start_sched > -1 && ast_sched_del(sched, event->bs_start_sched)) {
649 ast_debug(3, "Devicestate update (start) running, can't delete sched entry\n");
650 }
651 if (event->bs_end_sched > -1 && ast_sched_del(sched, event->bs_end_sched)) {
652 ast_debug(3, "Devicestate update (end) running, can't delete sched entry\n");
653 }
654
655 /* If an event is being deleted and we've fired an event changing the status at the beginning,
656 * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
657 if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
658 if (!calendar_is_busy(event->owner)) {
660 } else {
662 }
663 }
664
665 return NULL;
666}
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 758 of file res_calendar.c.

759{
760 struct ast_calendar_event *event = data;
761 struct ast_dial *dial = NULL;
762 struct ast_str *apptext = NULL, *tmpstr = NULL;
763 struct ast_datastore *datastore;
764 enum ast_dial_result res;
765 struct ast_channel *chan = NULL;
766 struct ast_variable *itervar;
767 char *tech, *dest;
768 char buf[33];
769 struct ast_format_cap *caps;
770
771 tech = ast_strdupa(event->owner->notify_channel);
772
773 if ((dest = strchr(tech, '/'))) {
774 *dest = '\0';
775 dest++;
776 } else {
777 ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
778 goto notify_cleanup;
779 }
780
781 if (!(dial = ast_dial_create())) {
782 ast_log(LOG_ERROR, "Could not create dial structure\n");
783 goto notify_cleanup;
784 }
785
786 if (ast_dial_append(dial, tech, dest, NULL) < 0) {
787 ast_log(LOG_ERROR, "Could not append channel\n");
788 goto notify_cleanup;
789 }
790
791 ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
793
794 if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, NULL, NULL, 0, "Calendar/%s-%s", event->owner->name, buf))) {
795 ast_log(LOG_ERROR, "Could not allocate notification channel\n");
796 goto notify_cleanup;
797 }
798
804
806 if (!caps) {
807 ast_log(LOG_ERROR, "Could not allocate capabilities, notification not being sent!\n");
808 goto notify_cleanup;
809 }
812 ao2_ref(caps, -1);
813
814 ast_channel_unlock(chan);
815
817 ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
818 goto notify_cleanup;
819 }
820
821 datastore->data = event;
823
824 ao2_ref(event, +1);
825
826 ast_channel_lock(chan);
827 res = ast_channel_datastore_add(chan, datastore);
828 ast_channel_unlock(chan);
829
830 if (!(tmpstr = ast_str_create(32))) {
831 goto notify_cleanup;
832 }
833
834 for (itervar = event->owner->vars; itervar; itervar = itervar->next) {
835 ast_str_substitute_variables(&tmpstr, 0, chan, itervar->value);
836 pbx_builtin_setvar_helper(chan, itervar->name, ast_str_buffer(tmpstr));
837 }
838
839 if (!(apptext = ast_str_create(32))) {
840 goto notify_cleanup;
841 }
842
843 if (!ast_strlen_zero(event->owner->notify_app)) {
844 ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata);
846 } else {
847 }
848
849 ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name);
850 res = ast_dial_run(dial, chan, 0);
851
852 if (res != AST_DIAL_RESULT_ANSWERED) {
853 ast_verb(3, "Notification call for %s was not completed\n", event->owner->name);
854 } else {
855 struct ast_channel *answered;
856
857 answered = ast_dial_answered_steal(dial);
858 if (ast_strlen_zero(event->owner->notify_app)) {
859 ast_channel_context_set(answered, event->owner->notify_context);
860 ast_channel_exten_set(answered, event->owner->notify_extension);
861 ast_channel_priority_set(answered, 1);
862 ast_pbx_run(answered);
863 }
864 }
865
866notify_cleanup:
867 if (apptext) {
868 ast_free(apptext);
869 }
870 if (tmpstr) {
871 ast_free(tmpstr);
872 }
873 if (dial) {
874 ast_dial_destroy(dial);
875 }
876 if (chan) {
878 }
879
881
882 return NULL;
883}
#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:1299
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:1551
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:4770
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:752
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 1859 of file res_calendar.c.

1860{
1861 for (;;) {
1862 struct timeval now = ast_tvnow();
1863 struct timespec ts = {0,};
1864 int wait;
1865
1867
1868 while (!module_unloading) {
1869 if ((wait = ast_sched_wait(sched)) < 0) {
1870 wait = 1000;
1871 }
1872
1873 ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
1874 if (ast_cond_timedwait(&refresh_condition, &refreshlock, &ts) == ETIMEDOUT) {
1875 break;
1876 }
1877 }
1879
1880 if (module_unloading) {
1881 break;
1882 }
1884 }
1885
1886 return NULL;
1887}
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:213
#define ast_mutex_unlock(a)
Definition: lock.h:197
#define ast_mutex_lock(a)
Definition: lock.h:196
static ast_mutex_t refreshlock
Definition: res_calendar.c:242
static ast_cond_t refresh_condition
Definition: res_calendar.c:243
static int module_unloading
Definition: res_calendar.c:245
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 1609 of file res_calendar.c.

1610{
1611 struct ast_tm tm;
1612 struct timeval tv = {
1613 .tv_sec = epoch,
1614 };
1615
1616 if (!epoch) {
1617 *buf = '\0';
1618 return buf;
1619 }
1620 ast_localtime(&tv, &tm, NULL);
1621 ast_strftime(buf, buflen, "%F %r %z", &tm);
1622
1623 return buf;
1624}
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 324 of file res_calendar.c.

325{
326 const struct ast_calendar_event *one = obj, *two = arg;
327 return !strcmp(one->uid, two->uid) ? CMP_MATCH | CMP_STOP : 0;
328}

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

319{
320 const struct ast_calendar_event *event = obj;
321 return ast_str_hash(event->uid);
322}
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 712 of file res_calendar.c.

713{
714 struct ast_calendar_event *event = data;
715
717
718}

References ast_calendar_unref_event().

◆ event_notification_duplicate()

static void * event_notification_duplicate ( void *  data)
static

Definition at line 720 of file res_calendar.c.

721{
722 struct ast_calendar_event *event = data;
723
724 if (!event) {
725 return NULL;
726 }
727
728 ao2_ref(event, +1);
729
730 return event;
731}

References ao2_ref, and NULL.

◆ eventlist_destroy()

static void eventlist_destroy ( void *  data)
static

Definition at line 1215 of file res_calendar.c.

1216{
1217 struct eventlist *events = data;
1218
1219 ao2_ref(events, -1);
1220}

References ao2_ref, and events.

◆ eventlist_destructor()

static void eventlist_destructor ( void *  obj)
static

Definition at line 364 of file res_calendar.c.

365{
366 struct eventlist *events = obj;
367 struct evententry *entry;
368
369 while ((entry = AST_LIST_REMOVE_HEAD(events, list))) {
370 ao2_ref(entry->event, -1);
371 ast_free(entry);
372 }
373}

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

Referenced by calendar_query_exec().

◆ eventlist_duplicate()

static void * eventlist_duplicate ( void *  data)
static

Definition at line 1222 of file res_calendar.c.

1223{
1224 struct eventlist *events = data;
1225
1226 if (!events) {
1227 return NULL;
1228 }
1229
1230 ao2_ref(events, +1);
1231
1232 return events;
1233}

References ao2_ref, events, and NULL.

◆ find_calendar()

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

Definition at line 310 of file res_calendar.c.

311{
312 struct ast_calendar tmp = {
313 .name = name,
314 };
315 return ao2_find(calendars, &tmp, OBJ_POINTER);
316}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, calendars, name, ast_calendar::name, and OBJ_POINTER.

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

◆ find_event()

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

Definition at line 330 of file res_calendar.c.

331{
332 struct ast_calendar_event tmp = {
333 .uid = uid,
334 };
335 return ao2_find(events, &tmp, OBJ_POINTER);
336}

References ao2_find, events, OBJ_POINTER, 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 734 of file res_calendar.c.

735{
736 unsigned long val[4];
737 int x;
738
739 for (x = 0; x < 4; x++) {
740 val[x] = ast_random();
741 }
742 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
743
744 return buf;
745}
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 1728 of file res_calendar.c.

1729{
1730 switch(cmd) {
1731 case CLI_INIT:
1732 e->command = "calendar dump sched";
1733 e->usage =
1734 "Usage: calendar dump sched\n"
1735 " Dump the calendar sched context";
1736 return NULL;
1737
1738 case CLI_GENERATE:
1739 return NULL;
1740 }
1741
1743
1744 return CLI_SUCCESS;
1745}
#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 1641 of file res_calendar.c.

1642{
1643#define FORMAT "%-18.18s : %-20.20s\n"
1644#define FORMAT2 "%-12.12s: %-40.60s\n"
1645 struct ao2_iterator i;
1646 struct ast_calendar *cal;
1647 struct ast_calendar_event *event;
1648 int which = 0;
1649 char *ret = NULL;
1650
1651 switch(cmd) {
1652 case CLI_INIT:
1653 e->command = "calendar show calendar";
1654 e->usage =
1655 "Usage: calendar show calendar <calendar name>\n"
1656 " Displays information about a calendar\n";
1657 return NULL;
1658
1659 case CLI_GENERATE:
1660 if (a->pos != 3) {
1661 return NULL;
1662 }
1664 while ((cal = ao2_iterator_next(&i))) {
1665 if (!strncasecmp(a->word, cal->name, strlen(a->word)) && ++which > a->n) {
1666 ret = ast_strdup(cal->name);
1667 cal = unref_calendar(cal);
1668 break;
1669 }
1670 cal = unref_calendar(cal);
1671 }
1673 return ret;
1674 }
1675
1676 if (a->argc != 4) {
1677 return CLI_SHOWUSAGE;
1678 }
1679
1680 if (!(cal = find_calendar(a->argv[3]))) {
1681 return NULL;
1682 }
1683
1684 ast_cli(a->fd, FORMAT, "Name", cal->name);
1685 ast_cli(a->fd, FORMAT, "Notify channel", cal->notify_channel);
1686 ast_cli(a->fd, FORMAT, "Notify context", cal->notify_context);
1687 ast_cli(a->fd, FORMAT, "Notify extension", cal->notify_extension);
1688 ast_cli(a->fd, FORMAT, "Notify application", cal->notify_app);
1689 ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata);
1690 ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh);
1691 ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe);
1692
1693 if (cal->autoreminder) {
1694 ast_cli(a->fd, "%-17.17s : %d minutes before event\n", "Autoreminder", cal->autoreminder);
1695 } else {
1696 ast_cli(a->fd, "%-17.17s : None\n", "Autoreminder");
1697 }
1698
1699 ast_cli(a->fd, "%s\n", "Events");
1700 ast_cli(a->fd, "%s\n", "------");
1701
1702 i = ao2_iterator_init(cal->events, 0);
1703 while ((event = ao2_iterator_next(&i))) {
1704 char buf[100];
1705
1706 ast_cli(a->fd, FORMAT2, "Summary", event->summary);
1707 ast_cli(a->fd, FORMAT2, "Description", event->description);
1708 ast_cli(a->fd, FORMAT2, "Organizer", event->organizer);
1709 ast_cli(a->fd, FORMAT2, "Location", event->location);
1710 ast_cli(a->fd, FORMAT2, "Categories", event->categories);
1711 ast_cli(a->fd, "%-12.12s: %d\n", "Priority", event->priority);
1712 ast_cli(a->fd, FORMAT2, "UID", event->uid);
1713 ast_cli(a->fd, FORMAT2, "Start", epoch_to_string(buf, sizeof(buf), event->start));
1714 ast_cli(a->fd, FORMAT2, "End", epoch_to_string(buf, sizeof(buf), event->end));
1715 ast_cli(a->fd, FORMAT2, "Alarm", epoch_to_string(buf, sizeof(buf), event->alarm));
1716 ast_cli(a->fd, FORMAT2, "Busy State", ast_calendar_busy_state_to_str(event->busy_state));
1717 ast_cli(a->fd, "\n");
1718
1720 }
1722 cal = unref_calendar(cal);
1723 return CLI_SUCCESS;
1724#undef FORMAT
1725#undef FORMAT2
1726}
#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 1550 of file res_calendar.c.

1551{
1552#define FORMAT "%-20.20s %-10.10s %-6.6s\n"
1553 struct ao2_iterator i;
1554 struct ast_calendar *cal;
1555
1556 switch(cmd) {
1557 case CLI_INIT:
1558 e->command = "calendar show calendars";
1559 e->usage =
1560 "Usage: calendar show calendars\n"
1561 " Lists all registered calendars.\n";
1562 return NULL;
1563 case CLI_GENERATE:
1564 return NULL;
1565 }
1566
1567 ast_cli(a->fd, FORMAT, "Calendar", "Type", "Status");
1568 ast_cli(a->fd, FORMAT, "--------", "----", "------");
1570 while ((cal = ao2_iterator_next(&i))) {
1571 ast_cli(a->fd, FORMAT, cal->name, cal->tech->type, calendar_is_busy(cal) ? "busy" : "free");
1572 cal = unref_calendar(cal);
1573 }
1575
1576 return CLI_SUCCESS;
1577#undef FORMAT
1578}

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

1582{
1583#define FORMAT "%-10.10s %-30.30s\n"
1584 struct ast_calendar_tech *iter;
1585
1586
1587 switch(cmd) {
1588 case CLI_INIT:
1589 e->command = "calendar show types";
1590 e->usage =
1591 "Usage: calendar show types\n"
1592 " Lists all registered calendars types.\n";
1593 return NULL;
1594 case CLI_GENERATE:
1595 return NULL;
1596 }
1597
1598 ast_cli(a->fd, FORMAT, "Type", "Description");
1600 AST_LIST_TRAVERSE(&techs, iter, list) {
1601 ast_cli(a->fd, FORMAT, iter->type, iter->description);
1602 }
1604
1605 return CLI_SUCCESS;
1606#undef FORMAT
1607}

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

1088{
1089 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1090 struct ast_config *tmpcfg;
1091
1092 if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
1093 tmpcfg == CONFIG_STATUS_FILEINVALID) {
1094 ast_log(LOG_ERROR, "Unable to load config calendar.conf\n");
1095 return -1;
1096 }
1097
1098 if (tmpcfg == CONFIG_STATUS_FILEUNCHANGED) {
1099 return 0;
1100 }
1101
1103 if (calendar_config) {
1105 }
1106
1107 calendar_config = tmpcfg;
1109
1110 return 0;
1111}
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:3541
@ CONFIG_FLAG_FILEUNCHANGED
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
#define ast_rwlock_wrlock(a)
Definition: lock.h:243
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 1938 of file res_calendar.c.

1939{
1942 if (!calendars) {
1943 ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
1945 }
1946
1947 if (load_config(0)) {
1948 /* We don't have calendar support enabled */
1950 }
1951
1955
1956 if (!(sched = ast_sched_context_create())) {
1957 ast_log(LOG_ERROR, "Unable to create sched context\n");
1961 }
1962
1964 ast_log(LOG_ERROR, "Unable to start refresh thread--notifications disabled!\n");
1965 }
1966
1973
1975
1977}
#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:394
#define ast_mutex_init(pmutex)
Definition: lock.h:193
@ 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:1559
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:244
static enum ast_device_state calendarstate(const char *data)
Definition: res_calendar.c:398
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:298
static pthread_t refresh_thread
Definition: res_calendar.c:241
static int calendar_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:304
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 530 of file res_calendar.c.

531{
532 struct ast_calendar *cal;
533 const char *cat = NULL;
534 const char *val;
535
536 if (!calendar_config) {
537 ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
538 return -1;
539 }
540
542 while ((cat = ast_category_browse(calendar_config, cat))) {
543 if (!strcasecmp(cat, "general")) {
544 continue;
545 }
546
547 if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) {
548 continue;
549 }
550
551 /* A serious error occurred loading calendars from this tech and it should be disabled */
552 if (!(cal = build_calendar(calendar_config, cat, tech))) {
555 return -1;
556 }
557
558 cal = unref_calendar(cal);
559 }
560
562
563 return 0;
564}
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:869
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
Definition: res_calendar.c:604
static struct ast_calendar * build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech)
Definition: res_calendar.c:417

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

593{
594 struct ast_calendar *cal = user_data;
595 struct ast_calendar_tech *tech = arg;
596
597 if (cal->tech == tech) {
598 return CMP_MATCH;
599 }
600
601 return 0;
602}

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

1039{
1040 struct ast_calendar_event *old_event = obj, *new_event;
1041 struct ao2_container *new_events = arg;
1042
1043 /* If we don't find the old_event in new_events, then we can safely delete the old_event */
1044 if (!(new_event = find_event(new_events, old_event->uid))) {
1045 old_event = destroy_event(old_event);
1046 return CMP_MATCH;
1047 }
1048
1049 /* We have events to merge. If any data that will affect a scheduler event has changed,
1050 * then we need to replace the scheduler event */
1051 schedule_calendar_event(old_event->owner, old_event, new_event);
1052
1053 /* Since we don't want to mess with cancelling sched events and adding new ones, just
1054 * copy the internals of the new_event to the old_event */
1055 copy_event_data(old_event, new_event);
1056
1057 /* Now we can go ahead and unlink the new_event from new_events and unref it so that only completely
1058 * new events remain in the container */
1059 ao2_unlink(new_events, new_event);
1060 new_event = ast_calendar_unref_event(new_event);
1061
1062 return 0;
1063}
static void copy_event_data(struct ast_calendar_event *dst, struct ast_calendar_event *src)
Definition: res_calendar.c:943
static struct ast_calendar_event * find_event(struct ao2_container *events, const char *uid)
Definition: res_calendar.c:330

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

748{
749 return 0;
750}

◆ reload()

static int reload ( void  )
static

Definition at line 1833 of file res_calendar.c.

1834{
1835 struct ast_calendar_tech *iter;
1836
1838
1839 /* Mark existing calendars for deletion */
1841 load_config(1);
1842
1844 AST_LIST_TRAVERSE(&techs, iter, list) {
1845 if (load_tech_calendars(iter)) {
1846 ast_log(LOG_WARNING, "Failed to reload %s calendars, module disabled\n", iter->type);
1847 }
1848 }
1850
1851 /* Delete calendars that no longer show up in the config */
1853
1855
1856 return 0;
1857}
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 971 of file res_calendar.c.

972{
973 struct timeval now = ast_tvnow();
975 time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end;
976 int changed = 0;
977
978 event = cmp_event ? cmp_event : old_event;
979
981 if (!ast_strlen_zero(cal->notify_channel) && (!cmp_event || old_event->alarm != event->alarm)) {
982 changed = 1;
983 if (cal->autoreminder) {
984 alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000;
985 } else if (event->alarm) {
986 alarm_notify_sched = (event->alarm - now.tv_sec) * 1000;
987 }
988
989 /* For now, send the notification if we missed it, but the meeting hasn't happened yet */
990 if (event->start >= now.tv_sec) {
991 if (alarm_notify_sched <= 0) {
992 alarm_notify_sched = 1;
993 }
995 AST_SCHED_REPLACE(old_event->notify_sched, sched, alarm_notify_sched, calendar_event_notify, old_event);
997 ast_debug(3, "Calendar alarm event notification scheduled to happen in %ld ms\n", (long) alarm_notify_sched);
998 }
999 }
1000
1001 if (!cmp_event || old_event->start != event->start) {
1002 changed = 1;
1003 devstate_sched_start = (event->start - now.tv_sec) * 1000;
1004
1005 if (devstate_sched_start < 1) {
1006 devstate_sched_start = 1;
1007 }
1008
1010 AST_SCHED_REPLACE(old_event->bs_start_sched, sched, devstate_sched_start, calendar_devstate_change, old_event);
1012 ast_debug(3, "Calendar bs_start event notification scheduled to happen in %ld ms\n", (long) devstate_sched_start);
1013 }
1014
1015 if (!cmp_event || old_event->end != event->end) {
1016 changed = 1;
1017 devstate_sched_end = (event->end - now.tv_sec) * 1000;
1018
1019 if (devstate_sched_end <= 0) { /* if we let this slip by, Asterisk will assert */
1020 ast_log(LOG_WARNING, "Whoops! Event end notification scheduled in the past: %ld ms\n", (long) devstate_sched_end);
1021 } else {
1023 AST_SCHED_REPLACE(old_event->bs_end_sched, sched, devstate_sched_end, calendar_devstate_change, old_event);
1025 ast_debug(3, "Calendar bs_end event notification scheduled to happen in %ld ms\n", (long) devstate_sched_end);
1026 }
1027 }
1028
1029 if (changed) {
1031 }
1032
1034
1035 return 0;
1036}
static int calendar_event_notify(const void *data)
Definition: res_calendar.c:885
static int calendar_devstate_change(const void *data)
Definition: res_calendar.c:909
#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 1890 of file res_calendar.c.

1891{
1892 struct ast_calendar_tech *tech;
1893
1894 ast_devstate_prov_del("calendar");
1901
1902 /* Remove all calendars */
1905 calendars = NULL;
1906
1908 module_unloading = 1;
1911 pthread_join(refresh_thread, NULL);
1912
1914
1917 ast_unload_resource(tech->module, 0);
1918 }
1921
1924
1925 return 0;
1926}
#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:421
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1457
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 1984 of file res_calendar.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1984 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 1136 of file res_calendar.c.

Referenced by load_module(), and unload_module().

◆ calendar_cli

struct ast_cli_entry calendar_cli[]
static

Definition at line 1747 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 1812 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 1321 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 1432 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 1544 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:720
static void event_notification_destroy(void *data)
Definition: res_calendar.c:712

Definition at line 252 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 258 of file res_calendar.c.

Referenced by calendar_query_exec(), and calendar_query_result_exec().

◆ module_unloading

int module_unloading
static

Definition at line 245 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:747

Definition at line 752 of file res_calendar.c.

Referenced by do_notify().

◆ refresh_condition

ast_cond_t refresh_condition
static

Definition at line 243 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 241 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 244 of file res_calendar.c.

Referenced by load_module(), and reload().

◆ sched

struct ast_sched_context* sched
static

Definition at line 240 of file res_calendar.c.

◆ techs

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