Asterisk - The Open Source Telephony Project  18.5.0
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)
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 220 of file res_calendar.c.

Referenced by ast_calendar_event_container_alloc(), build_calendar(), and load_module().

◆ 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"

Referenced by handle_show_calendar().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1946 of file res_calendar.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

References ao2_ref, ast_calloc, ast_debug, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_calendar_event::end, evententry::event, evententry::list, LOG_ERROR, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.

Referenced by calendar_query_exec().

1120 {
1121  struct evententry *entry, *iter;
1122  long event_startdiff = labs(start - event->start);
1123  long event_enddiff = labs(end - event->end);
1124  int i = 0;
1125 
1126  if (!(entry = ast_calloc(1, sizeof(*entry)))) {
1127  ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1128  return -1;
1129  }
1130 
1131  entry->event = event;
1132  ao2_ref(event, +1);
1133 
1134  if (start == end) {
1135  AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) {
1136  long startdiff = labs(iter->event->start - start);
1137 
1138  ast_debug(10, "Comparing %s with startdiff %ld to %s with startdiff %ld\n", event->summary, event_startdiff, iter->event->summary, startdiff);
1139  ++i;
1140  if (startdiff > event_startdiff) {
1142  return i;
1143  }
1144  if (startdiff == event_startdiff) {
1145  long enddiff = labs(iter->event->end - end);
1146 
1147  if (enddiff > event_enddiff) {
1149  return i;
1150  }
1151  if (event_startdiff == enddiff) {
1152  if (strcmp(event->uid, iter->event->uid) < 0) {
1154  return i;
1155  }
1156  }
1157  }
1158  }
1160 
1161  AST_LIST_INSERT_TAIL(events, entry, list);
1162 
1163  return i;
1164  }
1165 
1166  AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) {
1167  ++i;
1168  if (iter->event->start > event->start) {
1170  return i;
1171  }
1172 
1173  if (iter->event->start == event->start) {
1174  if ((iter->event->end - iter->event->start) == (event->end - event->start)) {
1175  if (strcmp(event->uid, iter->event->uid) < 0) {
1177  return i;
1178  }
1179  }
1180  if ((iter->event->end - iter->event->start) < (event->end - event->start)) {
1182  return i;
1183  }
1184  }
1185  }
1187 
1188  AST_LIST_INSERT_TAIL(events, entry, list);
1189 
1190  return i;
1191 }
const ast_string_field uid
Definition: calendar.h:101
char * end
Definition: eagi_proxy.c:73
struct evententry::@447 list
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_calendar_event * event
Definition: res_calendar.c:248
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
Definition: linkedlists.h:598
const ast_string_field summary
Definition: calendar.h:101

◆ add_new_event_cb()

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

Definition at line 1043 of file res_calendar.c.

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

Referenced by ast_calendar_merge_events().

1044 {
1045  struct ast_calendar_event *new_event = obj;
1046  struct ao2_container *events = arg;
1047 
1048  ao2_link(events, new_event);
1049  schedule_calendar_event(new_event->owner, new_event, NULL);
1050  return CMP_MATCH;
1051 }
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define NULL
Definition: resample.c:96
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:954
struct ast_calendar * owner
Definition: calendar.h:103
Generic container type.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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

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

661 {
662  ast_debug(3, "Clearing all events for calendar %s\n", cal->name);
663 
665 }
static int clear_events_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:651
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const ast_string_field name
Definition: calendar.h:127
struct ao2_container * events
Definition: calendar.h:138

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

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

259 {
261 
262  if (!calendar_config) {
264  return NULL;
265  }
266 
267  return calendar_config;
268 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static struct ast_config * calendar_config
Definition: res_calendar.c:255
static ast_rwlock_t config_lock
Definition: res_calendar.c:256

◆ ast_calendar_config_release()

void ast_calendar_config_release ( void  )

Release the calendar config.

Definition at line 270 of file res_calendar.c.

References ast_rwlock_unlock, and config_lock.

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

271 {
273 }
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static ast_rwlock_t config_lock
Definition: res_calendar.c:256

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

References ao2_alloc, ast_calendar_unref_event(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_calendar_event::attendees, calendar_event_destructor(), evententry::event, and NULL.

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

668 {
669  struct ast_calendar_event *event;
670  if (!(event = ao2_alloc(sizeof(*event), calendar_event_destructor))) {
671  return NULL;
672  }
673 
674  if (ast_string_field_init(event, 32)) {
675  event = ast_calendar_unref_event(event);
676  return NULL;
677  }
678 
679  event->owner = cal;
680  event->notify_sched = -1;
681  event->bs_start_sched = -1;
682  event->bs_end_sched = -1;
683 
685 
686  return event;
687 }
Definition: astman.c:222
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
static void calendar_event_destructor(void *obj)
Definition: res_calendar.c:609
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ast_calendar_event::attendees attendees
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321

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

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

690 {
693 }
static int event_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:301
#define NULL
Definition: resample.c:96
#define CALENDAR_BUCKETS
Definition: res_calendar.c:220
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int event_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:307

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

References add_new_event_cb(), ao2_callback, ast_calendar::events, merge_events_cb(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by endelm(), icalendar_update_events(), startelm(), update_caldav(), and update_exchangecal().

1054 {
1055  /* Loop through all events attached to the calendar. If there is a matching new event
1056  * merge its data over and handle any schedule changes that need to be made. Then remove
1057  * the new_event from new_events so that we are left with only new_events that we can add later. */
1059 
1060  /* Now, we should only have completely new events in new_events. Loop through and add them */
1062 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ao2_container * events
Definition: calendar.h:138
static int merge_events_cb(void *obj, void *arg, int flags)
static int add_new_event_cb(void *obj, void *arg, int flags)

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

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

Referenced by load_module().

550 {
551  struct ast_calendar_tech *iter;
552 
553  if (!calendar_config) {
554  ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
555  return -1;
556  }
557 
559  AST_LIST_TRAVERSE(&techs, iter, list) {
560  if(!strcasecmp(tech->type, iter->type)) {
561  ast_log(LOG_WARNING, "Already have a handler for calendar type '%s'\n", tech->type);
563  return -1;
564  }
565  }
567  tech->user = ast_module_user_add(NULL);
569 
570  ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description);
571 
572  return load_tech_calendars(tech);
573 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int load_tech_calendars(struct ast_calendar_tech *tech)
Definition: res_calendar.c:513
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_calendar_tech::@239 list
struct ast_module_user * user
Definition: calendar.h:73
const char * description
Definition: calendar.h:71
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
const char * type
Definition: calendar.h:70
#define ast_log
Definition: astobj2.c:42
#define ast_module_user_add(chan)
Definition: module.h:426
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
static struct ast_config * calendar_config
Definition: res_calendar.c:255
Individual calendaring technology data.
Definition: calendar.h:69

◆ ast_calendar_unref_event()

struct ast_calendar_event* ast_calendar_unref_event ( struct ast_calendar_event event)

Unreference an ast_calendar_event.

Parameters
eventevent to unref
Returns
NULL

Definition at line 321 of file res_calendar.c.

References ao2_ref, and NULL.

Referenced by ast_calendar_event_alloc(), caldav_add_event(), calendar_devstate_change(), calendar_query_exec(), calendar_write_exec(), do_notify(), endelm(), event_notification_destroy(), handle_show_calendar(), icalendar_add_event(), merge_events_cb(), and parse_tag().

322 {
323  ao2_ref(event, -1);
324  return NULL;
325 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ ast_calendar_unregister()

void ast_calendar_unregister ( struct ast_calendar_tech tech)

Unregister a new calendar technology.

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

Definition at line 587 of file res_calendar.c.

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

Referenced by load_tech_calendars(), and unload_module().

588 {
589  struct ast_calendar_tech *iter;
590 
593  if (iter != tech) {
594  continue;
595  }
596 
598 
601  ast_verb(2, "Unregistered calendar type '%s'\n", tech->type);
602  break;
603  }
606 
607 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ao2_container * calendars
Definition: res_calendar.c:222
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ast_calendar_tech::@239 list
struct ast_module_user * user
Definition: calendar.h:73
#define ast_module_user_remove(user)
Definition: module.h:427
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_verb(level,...)
Definition: logger.h:463
const char * type
Definition: calendar.h:70
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
static int match_caltech_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:575
Individual calendaring technology data.
Definition: calendar.h:69
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

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

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(), 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_variable::name, ast_calendar::name, 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(), value, ast_variable::value, var, and ast_calendar::vars.

Referenced by load_tech_calendars().

401 {
402  struct ast_calendar *cal;
403  struct ast_variable *v, *last = NULL;
404  int new_calendar = 0;
405 
406  cal = find_calendar(cat);
407  if (cal && cal->fetch_again_at_reload) {
408  /** Create new calendar, old will be removed during reload */
409  cal = unref_calendar(cal);
410  }
411  if (!cal) {
412  new_calendar = 1;
413  if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) {
414  ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n");
415  return NULL;
416  }
417 
420  if (!cal->events) {
421  ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat);
422  cal = unref_calendar(cal);
423  return NULL;
424  }
425 
426  if (ast_string_field_init(cal, 32)) {
427  ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat);
428  cal = unref_calendar(cal);
429  return NULL;
430  }
431  } else {
432  cal->pending_deletion = 0;
433  }
434 
435  ast_string_field_set(cal, name, cat);
436  cal->tech = tech;
437 
438  cal->refresh = 3600;
439  cal->timeframe = 60;
440  cal->notify_waittime = 30000;
441  cal->fetch_again_at_reload = 0;
442 
443  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
444  if (!strcasecmp(v->name, "autoreminder")) {
445  cal->autoreminder = atoi(v->value);
446  } else if (!strcasecmp(v->name, "channel")) {
448  } else if (!strcasecmp(v->name, "context")) {
449  ast_string_field_set(cal, notify_context, v->value);
450  } else if (!strcasecmp(v->name, "extension")) {
451  ast_string_field_set(cal, notify_extension, v->value);
452  } else if (!strcasecmp(v->name, "waittime")) {
453  int i = atoi(v->value);
454  if (i > 0) {
455  cal->notify_waittime = 1000 * i;
456  }
457  } else if (!strcasecmp(v->name, "app")) {
458  ast_string_field_set(cal, notify_app, v->value);
459  } else if (!strcasecmp(v->name, "appdata")) {
460  ast_string_field_set(cal, notify_appdata, v->value);
461  } else if (!strcasecmp(v->name, "refresh")) {
462  cal->refresh = atoi(v->value);
463  } else if (!strcasecmp(v->name, "fetch_again_at_reload")) {
465  } else if (!strcasecmp(v->name, "timeframe")) {
466  cal->timeframe = atoi(v->value);
467  } else if (!strcasecmp(v->name, "setvar")) {
468  char *name, *value;
469  struct ast_variable *var;
470 
471  if ((name = (value = ast_strdup(v->value)))) {
472  strsep(&value, "=");
473  if (value) {
474  if ((var = ast_variable_new(ast_strip(name), ast_strip(value), ""))) {
475  if (last) {
476  last->next = var;
477  } else {
478  cal->vars = var;
479  }
480  last = var;
481  }
482  } else {
483  ast_log(LOG_WARNING, "Malformed argument. Should be '%s: variable=value'\n", v->name);
484  }
485  ast_free(name);
486  }
487  }
488  }
489 
490  if (cal->autoreminder && ast_strlen_zero(cal->notify_channel)) {
492  "You have set 'autoreminder' but not 'channel' for calendar '%s.' "
493  "Notifications will not occur.\n",
494  cal->name);
495  }
496 
497  if (new_calendar) {
498  cal->thread = AST_PTHREADT_NULL;
499  ast_cond_init(&cal->unload, NULL);
500  ao2_link(calendars, cal);
501  if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) {
502  /* If we start failing to create threads, go ahead and return NULL
503  * and the tech module will be unregistered
504  */
505  ao2_unlink(calendars, cal);
506  cal = unref_calendar(cal);
507  }
508  }
509 
510  return cal;
511 }
struct ast_variable * next
int fetch_again_at_reload
Definition: calendar.h:132
ast_cond_t unload
Definition: calendar.h:135
const struct ast_calendar_tech * tech
Definition: calendar.h:118
static struct ao2_container * calendars
Definition: res_calendar.c:222
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
struct ast_variable * vars
Definition: calendar.h:128
#define LOG_WARNING
Definition: logger.h:274
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:293
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static int event_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:301
#define ast_cond_init(cond, attr)
Definition: lock.h:199
int notify_waittime
Definition: calendar.h:130
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
int timeframe
Definition: calendar.h:133
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define CALENDAR_BUCKETS
Definition: res_calendar.c:220
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define AST_PTHREADT_NULL
Definition: lock.h:66
struct sla_ringing_trunk * last
Definition: app_meetme.c:1092
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
static void calendar_destructor(void *obj)
Definition: res_calendar.c:327
#define ast_variable_new(name, value, filename)
const ast_string_field name
Definition: calendar.h:127
struct ao2_container * events
Definition: calendar.h:138
pthread_t thread
Definition: calendar.h:134
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
void *(* load_calendar)(void *data)
Definition: calendar.h:75
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
static int event_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:307
unsigned int pending_deletion
Definition: calendar.h:137
char * strsep(char **str, const char *delims)
static int notify_channel(void *obj)
Asterisk calendar structure.
Definition: calendar.h:117
int autoreminder
Definition: calendar.h:129
const ast_string_field notify_channel
Definition: calendar.h:127
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ calendar_busy_callback()

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

Definition at line 358 of file res_calendar.c.

References AST_CALENDAR_BS_FREE, ast_tvnow(), and CMP_STOP.

Referenced by calendar_is_busy().

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

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

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

1093 {
1094  struct ast_calendar *cal;
1095 
1096  if (ast_strlen_zero(data)) {
1097  ast_log(LOG_WARNING, "CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n");
1098  return -1;
1099  }
1100 
1101  cal = find_calendar(data);
1102 
1103  if (!cal) {
1104  ast_log(LOG_WARNING, "Could not find calendar '%s'\n", data);
1105  return -1;
1106  }
1107 
1108  strcpy(buf, calendar_is_busy(cal) ? "1" : "0");
1109  cal = unref_calendar(cal);
1110 
1111  return 0;
1112 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:293
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:372
Asterisk calendar structure.
Definition: calendar.h:117

◆ calendar_cmp_fn()

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

Definition at line 287 of file res_calendar.c.

References CMP_MATCH, CMP_STOP, and ast_calendar::name.

Referenced by load_module().

288 {
289  const struct ast_calendar *one = obj, *two = arg;
290  return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP: 0;
291 }
const ast_string_field name
Definition: calendar.h:127
Asterisk calendar structure.
Definition: calendar.h:117

◆ calendar_destructor()

static void calendar_destructor ( void *  obj)
static

Definition at line 327 of file res_calendar.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_calendar_clear_events(), ast_cond_signal, ast_debug, ast_string_field_free_memory, ast_variables_destroy(), ast_calendar::events, ast_calendar::name, 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().

328 {
329  struct ast_calendar *cal = obj;
330 
331  ast_debug(3, "Destroying calendar %s\n", cal->name);
332 
333  ao2_lock(cal);
334  cal->unloading = 1;
335  ast_cond_signal(&cal->unload);
336  pthread_join(cal->thread, NULL);
337  if (cal->tech_pvt) {
338  cal->tech_pvt = cal->tech->unref_calendar(cal->tech_pvt);
339  }
343  ao2_ref(cal->events, -1);
344  ao2_unlock(cal);
345 }
ast_cond_t unload
Definition: calendar.h:135
unsigned int unloading
Definition: calendar.h:136
const struct ast_calendar_tech * tech
Definition: calendar.h:118
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_variable * vars
Definition: calendar.h:128
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
void * tech_pvt
Definition: calendar.h:119
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void *(* unref_calendar)(void *obj)
Definition: calendar.h:76
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field name
Definition: calendar.h:127
struct ao2_container * events
Definition: calendar.h:138
pthread_t thread
Definition: calendar.h:134
Asterisk calendar structure.
Definition: calendar.h:117
void ast_calendar_clear_events(struct ast_calendar *cal)
Remove all events from calendar.
Definition: res_calendar.c:660
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ calendar_devstate_change()

static int calendar_devstate_change ( const void *  data)
static

Definition at line 892 of file res_calendar.c.

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

Referenced by schedule_calendar_event().

893 {
894  struct ast_calendar_event *event = (struct ast_calendar_event *)data;
895  struct timeval now = ast_tvnow();
896  int is_end_event;
897 
898  if (!event) {
899  ast_log(LOG_WARNING, "Event was NULL!\n");
900  return 0;
901  }
902 
903  ao2_ref(event, +1);
904 
905  is_end_event = event->end <= now.tv_sec;
906 
907  if (is_end_event) {
908  event->bs_end_sched = -1;
909  } else {
910  event->bs_start_sched = -1;
911  }
912 
913  /* We can have overlapping events, so ignore the event->busy_state and check busy state
914  * based on all events in the calendar */
915  if (!calendar_is_busy(event->owner)) {
917  } else {
918  ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
919  }
920 
922 
923  return 0;
924 }
#define LOG_WARNING
Definition: logger.h:274
Definition: astman.c:222
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_log
Definition: astobj2.c:42
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:372
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321

◆ calendar_event_destructor()

static void calendar_event_destructor ( void *  obj)
static

Definition at line 609 of file res_calendar.c.

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

Referenced by ast_calendar_event_alloc().

610 {
611  struct ast_calendar_event *event = obj;
612  struct ast_calendar_attendee *attendee;
613 
614  ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name);
616  while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) {
617  if (attendee->data) {
618  ast_free(attendee->data);
619  }
620  ast_free(attendee);
621  }
622 }
struct ast_calendar_attendee * next
Definition: calendar.h:89
Definition: astman.c:222
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ calendar_event_notify()

static int calendar_event_notify ( const void *  data)
static

Definition at line 868 of file res_calendar.c.

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

Referenced by schedule_calendar_event().

869 {
870  struct ast_calendar_event *event = (void *)data;
871  int res = -1;
872  pthread_t notify_thread = AST_PTHREADT_NULL;
873 
874  if (!(event && event->owner)) {
875  ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
876  return res;
877  }
878 
879  ao2_ref(event, +1);
880  event->notify_sched = -1;
881 
882  if (ast_pthread_create_background(&notify_thread, NULL, do_notify, event) < 0) {
883  ast_log(LOG_ERROR, "Could not create notification thread\n");
884  return res;
885  }
886 
887  res = 0;
888 
889  return res;
890 }
static void * do_notify(void *data)
Definition: res_calendar.c:741
Definition: astman.c:222
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_log
Definition: astobj2.c:42
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285

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

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), ast_log, ast_strlen_zero, ast_calendar_event::busy_state, calendar_join_attendees(), ast_calendar_event::categories, ast_datastore::data, ast_calendar_event::description, ast_calendar_event::end, evententry::event, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, NULL, 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.

1717 {
1718  struct ast_datastore *datastore;
1719  struct ast_calendar_event *event;
1720 
1721  if (!chan) {
1722  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1723  return -1;
1724  }
1725 
1726  if (ast_strlen_zero(data)) {
1727  ast_log(LOG_WARNING, "%s requires an argument\n", cmd);
1728  return -1;
1729  }
1730 
1731  ast_channel_lock(chan);
1732  if (!(datastore = ast_channel_datastore_find(chan, &event_notification_datastore, NULL))) {
1733  ast_log(LOG_WARNING, "There is no event notification datastore on '%s'!\n", ast_channel_name(chan));
1734  ast_channel_unlock(chan);
1735  return -1;
1736  }
1737  ast_channel_unlock(chan);
1738 
1739  if (!(event = datastore->data)) {
1740  ast_log(LOG_WARNING, "The datastore contains no data!\n");
1741  return -1;
1742  }
1743 
1744  if (!strcasecmp(data, "summary")) {
1745  ast_copy_string(buf, event->summary, len);
1746  } else if (!strcasecmp(data, "description")) {
1747  ast_copy_string(buf, event->description, len);
1748  } else if (!strcasecmp(data, "organizer")) {
1749  ast_copy_string(buf, event->organizer, len);
1750  } else if (!strcasecmp(data, "location")) {
1751  ast_copy_string(buf, event->location, len);
1752  } else if (!strcasecmp(data, "categories")) {
1753  ast_copy_string(buf, event->categories, len);
1754  } else if (!strcasecmp(data, "priority")) {
1755  snprintf(buf, len, "%d", event->priority);
1756  } else if (!strcasecmp(data, "calendar")) {
1757  ast_copy_string(buf, event->owner->name, len);
1758  } else if (!strcasecmp(data, "uid")) {
1759  ast_copy_string(buf, event->uid, len);
1760  } else if (!strcasecmp(data, "start")) {
1761  snprintf(buf, len, "%ld", (long)event->start);
1762  } else if (!strcasecmp(data, "end")) {
1763  snprintf(buf, len, "%ld", (long)event->end);
1764  } else if (!strcasecmp(data, "busystate")) {
1765  snprintf(buf, len, "%u", event->busy_state);
1766  } else if (!strcasecmp(data, "attendees")) {
1767  calendar_join_attendees(event, buf, len);
1768  }
1769 
1770 
1771  return 0;
1772 }
static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
#define ast_channel_lock(chan)
Definition: channel.h:2945
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
Definition: astman.c:222
const ast_string_field uid
Definition: calendar.h:101
enum ast_calendar_busy_state busy_state
Definition: calendar.h:107
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
const ast_string_field description
Definition: calendar.h:101
const ast_string_field organizer
Definition: calendar.h:101
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const ast_string_field location
Definition: calendar.h:101
const ast_string_field name
Definition: calendar.h:127
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_calendar * owner
Definition: calendar.h:103
const ast_string_field categories
Definition: calendar.h:101
void * data
Definition: datastore.h:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
static const struct ast_datastore_info event_notification_datastore
Definition: res_calendar.c:235
const ast_string_field summary
Definition: calendar.h:101

◆ calendar_hash_fn()

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

Definition at line 281 of file res_calendar.c.

References ast_str_case_hash(), and ast_calendar::name.

Referenced by load_module().

282 {
283  const struct ast_calendar *cal = obj;
284  return ast_str_case_hash(cal->name);
285 }
const ast_string_field name
Definition: calendar.h:127
Asterisk calendar structure.
Definition: calendar.h:117
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:1250

◆ calendar_is_busy()

static int calendar_is_busy ( struct ast_calendar cal)
static

Definition at line 372 of file res_calendar.c.

References ao2_callback, calendar_busy_callback(), ast_calendar::events, and OBJ_NODATA.

Referenced by calendar_busy_exec(), calendar_devstate_change(), calendarstate(), destroy_event(), and handle_show_calendars().

373 {
374  int is_busy = 0;
375 
377 
378  return is_busy;
379 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static int calendar_busy_callback(void *obj, void *arg, int flags)
Definition: res_calendar.c:358
struct ao2_container * events
Definition: calendar.h:138

◆ calendar_join_attendees()

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

Definition at line 1304 of file res_calendar.c.

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

Referenced by calendar_event_read(), and calendar_query_result_exec().

1305 {
1306  struct ast_str *tmp;
1307  struct ast_calendar_attendee *attendee;
1308 
1309  if (!(tmp = ast_str_create(32))) {
1310  ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n");
1311  return;
1312  }
1313 
1314  AST_LIST_TRAVERSE(&event->attendees, attendee, next) {
1315  ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data);
1316  }
1317 
1319  ast_free(tmp);
1320 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
struct ast_calendar_attendee * next
Definition: calendar.h:89
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:1091
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
struct ast_calendar_event::attendees attendees
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

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

1214 {
1215  struct ast_calendar *cal;
1216  struct ao2_iterator i;
1217  struct ast_calendar_event *event;
1218  struct eventlist *events;
1219  time_t start = INT_MIN, end = INT_MAX;
1220  struct ast_datastore *eventlist_datastore;
1222  AST_APP_ARG(calendar);
1223  AST_APP_ARG(start);
1224  AST_APP_ARG(end);
1225  );
1226 
1227  if (!chan) {
1228  ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd);
1229  return -1;
1230  }
1231 
1233 
1234  if (ast_strlen_zero(args.calendar)) {
1235  ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd);
1236  return -1;
1237  }
1238 
1239  if (!(cal = find_calendar(args.calendar))) {
1240  ast_log(LOG_WARNING, "Unknown calendar '%s'\n", args.calendar);
1241  return -1;
1242  }
1243 
1244  if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) {
1245  ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1246  cal = unref_calendar(cal);
1247  return -1;
1248  }
1249 
1250  if (!ast_strlen_zero(args.start)) {
1251  start = atoi(args.start);
1252  }
1253 
1254  if (!ast_strlen_zero(args.end)) {
1255  end = atoi(args.end);
1256  }
1257 
1258  i = ao2_iterator_init(cal->events, 0);
1259  while ((event = ao2_iterator_next(&i))) {
1260  if (!(start > event->end || end < event->start)) {
1261  ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end);
1262  if (add_event_to_list(events, event, start, end) < 0) {
1263  event = ast_calendar_unref_event(event);
1264  cal = unref_calendar(cal);
1265  ao2_ref(events, -1);
1267  return -1;
1268  }
1269  }
1270 
1271  event = ast_calendar_unref_event(event);
1272  }
1274 
1275  ast_channel_lock(chan);
1276  do {
1279  ast_channel_unlock(chan);
1280 
1281  if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) {
1282  ast_log(LOG_ERROR, "Could not allocate datastore!\n");
1283  cal = unref_calendar(cal);
1284  ao2_ref(events, -1);
1285  return -1;
1286  }
1287 
1288  eventlist_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1289  eventlist_datastore->data = events;
1290 
1291  ast_channel_lock(chan);
1292  ast_channel_datastore_add(chan, eventlist_datastore);
1293  ast_channel_unlock(chan);
1294 
1295  cal = unref_calendar(cal);
1296  return 0;
1297 }
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:717
#define ast_channel_lock(chan)
Definition: channel.h:2945
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:293
Definition: astman.c:222
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
Structure for a data store object.
Definition: datastore.h:68
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:2404
const char * args
static void eventlist_destructor(void *obj)
Definition: res_calendar.c:347
char * end
Definition: eagi_proxy.c:73
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static const struct ast_datastore_info eventlist_datastore_info
Definition: res_calendar.c:241
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * events
Definition: calendar.h:138
#define LOG_ERROR
Definition: logger.h:285
static int add_event_to_list(struct eventlist *events, struct ast_calendar_event *event, time_t start, time_t end)
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:193
unsigned int inheritance
Definition: datastore.h:73
void * data
Definition: datastore.h:70
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
Asterisk calendar structure.
Definition: calendar.h:117
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321
const ast_string_field summary
Definition: calendar.h:101
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define AST_APP_ARG(name)
Define an application argument.

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

References args, AST_APP_ARG, ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero, ast_calendar_event::busy_state, calendar_join_attendees(), ast_calendar_event::categories, ast_datastore::data, ast_calendar_event::description, ast_calendar_event::end, evententry::event, events, evententry::list, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.

1323 {
1324  struct ast_datastore *datastore;
1325  struct eventlist *events;
1326  struct evententry *entry;
1327  int row = 1;
1328  size_t listlen = 0;
1330  AST_APP_ARG(id);
1331  AST_APP_ARG(field);
1332  AST_APP_ARG(row);
1333  );
1334 
1335  if (!chan) {
1336  ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
1337  return -1;
1338  }
1339 
1340  AST_STANDARD_APP_ARGS(args, data);
1341 
1342  if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) {
1343  ast_log(LOG_WARNING, "%s requires an id and a field", cmd);
1344  return -1;
1345  }
1346 
1347  ast_channel_lock(chan);
1348  if (!(datastore = ast_channel_datastore_find(chan, &eventlist_datastore_info, args.id))) {
1349  ast_log(LOG_WARNING, "There is no event notification datastore with id '%s' on '%s'!\n", args.id, ast_channel_name(chan));
1350  ast_channel_unlock(chan);
1351  return -1;
1352  }
1353  ast_channel_unlock(chan);
1354 
1355  if (!(events = datastore->data)) {
1356  ast_log(LOG_WARNING, "The datastore contains no data!\n");
1357  return -1;
1358  }
1359 
1360  if (!ast_strlen_zero(args.row)) {
1361  row = atoi(args.row);
1362  }
1363 
1364  AST_LIST_TRAVERSE(events, entry, list) {
1365  listlen++;
1366  }
1367 
1368  if (!strcasecmp(args.field, "getnum")) {
1369  snprintf(buf, len, "%zu", listlen);
1370  return 0;
1371  }
1372 
1373  AST_LIST_TRAVERSE(events, entry, list) {
1374  if (--row) {
1375  continue;
1376  }
1377  if (!strcasecmp(args.field, "summary")) {
1378  ast_copy_string(buf, entry->event->summary, len);
1379  } else if (!strcasecmp(args.field, "description")) {
1381  } else if (!strcasecmp(args.field, "organizer")) {
1382  ast_copy_string(buf, entry->event->organizer, len);
1383  } else if (!strcasecmp(args.field, "location")) {
1384  ast_copy_string(buf, entry->event->location, len);
1385  } else if (!strcasecmp(args.field, "categories")) {
1386  ast_copy_string(buf, entry->event->categories, len);
1387  } else if (!strcasecmp(args.field, "priority")) {
1388  snprintf(buf, len, "%d", entry->event->priority);
1389  } else if (!strcasecmp(args.field, "calendar")) {
1390  ast_copy_string(buf, entry->event->owner->name, len);
1391  } else if (!strcasecmp(args.field, "uid")) {
1392  ast_copy_string(buf, entry->event->uid, len);
1393  } else if (!strcasecmp(args.field, "start")) {
1394  snprintf(buf, len, "%ld", (long) entry->event->start);
1395  } else if (!strcasecmp(args.field, "end")) {
1396  snprintf(buf, len, "%ld", (long) entry->event->end);
1397  } else if (!strcasecmp(args.field, "busystate")) {
1398  snprintf(buf, len, "%u", entry->event->busy_state);
1399  } else if (!strcasecmp(args.field, "attendees")) {
1401  } else {
1402  ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field);
1403  }
1404  break;
1405  }
1406 
1407  return 0;
1408 }
static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
#define ast_channel_lock(chan)
Definition: channel.h:2945
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
const ast_string_field uid
Definition: calendar.h:101
enum ast_calendar_busy_state busy_state
Definition: calendar.h:107
Structure for a data store object.
Definition: datastore.h:68
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:2404
const char * args
struct evententry::@447 list
const ast_string_field description
Definition: calendar.h:101
const ast_string_field organizer
Definition: calendar.h:101
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const ast_string_field location
Definition: calendar.h:101
static const struct ast_datastore_info eventlist_datastore_info
Definition: res_calendar.c:241
const ast_string_field name
Definition: calendar.h:127
struct ast_calendar_event * event
Definition: res_calendar.c:248
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_calendar * owner
Definition: calendar.h:103
const ast_string_field categories
Definition: calendar.h:101
void * data
Definition: datastore.h:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
Definition: search.h:40
const ast_string_field summary
Definition: calendar.h:101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ calendar_write_exec()

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

Definition at line 1415 of file res_calendar.c.

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

1416 {
1417  int i, j, ret = -1;
1418  char *val_dup = NULL;
1419  struct ast_calendar *cal = NULL;
1420  struct ast_calendar_event *event = NULL;
1421  struct timeval tv = ast_tvnow();
1422  AST_DECLARE_APP_ARGS(fields,
1423  AST_APP_ARG(field)[10];
1424  );
1426  AST_APP_ARG(value)[10];
1427  );
1428 
1429  if (!(val_dup = ast_strdup(value))) {
1430  ast_log(LOG_ERROR, "Could not allocate memory for values\n");
1431  goto write_cleanup;
1432  }
1433 
1434  AST_STANDARD_APP_ARGS(fields, data);
1435  AST_STANDARD_APP_ARGS(values, val_dup);
1436 
1437  /* XXX Eventually we will support unnamed calendars, so if we don't find one, we parse
1438  * for a calendar type and create it */
1439  if (!(cal = find_calendar(fields.field[0]))) {
1440  ast_log(LOG_WARNING, "Couldn't find calendar '%s'\n", fields.field[0]);
1441  goto write_cleanup;
1442  }
1443 
1444  if (!(cal->tech->write_event)) {
1445  ast_log(LOG_WARNING, "Calendar '%s' has no write function!\n", cal->name);
1446  goto write_cleanup;
1447  }
1448 
1449  if (!(event = ast_calendar_event_alloc(cal))) {
1450  goto write_cleanup;
1451  }
1452 
1453  if (ast_strlen_zero(fields.field[0])) {
1454  ast_log(LOG_WARNING, "CALENDAR_WRITE requires a calendar name!\n");
1455  goto write_cleanup;
1456  }
1457 
1458  if (fields.argc - 1 != values.argc) {
1459  ast_log(LOG_WARNING, "CALENDAR_WRITE should have the same number of fields (%u) and values (%u)!\n", fields.argc - 1, values.argc);
1460  goto write_cleanup;
1461  }
1462 
1463  event->owner = cal;
1464 
1465  for (i = 1, j = 0; i < fields.argc; i++, j++) {
1466  if (!strcasecmp(fields.field[i], "summary")) {
1467  ast_string_field_set(event, summary, values.value[j]);
1468  } else if (!strcasecmp(fields.field[i], "description")) {
1469  ast_string_field_set(event, description, values.value[j]);
1470  } else if (!strcasecmp(fields.field[i], "organizer")) {
1471  ast_string_field_set(event, organizer, values.value[j]);
1472  } else if (!strcasecmp(fields.field[i], "location")) {
1473  ast_string_field_set(event, location, values.value[j]);
1474  } else if (!strcasecmp(fields.field[i], "categories")) {
1476  } else if (!strcasecmp(fields.field[i], "priority")) {
1477  event->priority = atoi(values.value[j]);
1478  } else if (!strcasecmp(fields.field[i], "uid")) {
1479  ast_string_field_set(event, uid, values.value[j]);
1480  } else if (!strcasecmp(fields.field[i], "start")) {
1481  event->start = atoi(values.value[j]);
1482  } else if (!strcasecmp(fields.field[i], "end")) {
1483  event->end = atoi(values.value[j]);
1484  } else if (!strcasecmp(fields.field[i], "busystate")) {
1485  event->busy_state = atoi(values.value[j]);
1486  } else {
1487  ast_log(LOG_WARNING, "Unknown calendar event field '%s'\n", fields.field[i]);
1488  }
1489  }
1490 
1491  if (!event->start) {
1492  event->start = tv.tv_sec;
1493  }
1494 
1495  if (!event->end) {
1496  event->end = tv.tv_sec;
1497  }
1498 
1499  if((ret = cal->tech->write_event(event))) {
1500  ast_log(LOG_WARNING, "Writing event to calendar '%s' failed!\n", cal->name);
1501  }
1502 
1503 write_cleanup:
1504  if (ret) {
1505  pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "0");
1506  } else {
1507  pbx_builtin_setvar_helper(chan, "CALENDAR_SUCCESS", "1");
1508  }
1509  if (cal) {
1510  cal = unref_calendar(cal);
1511  }
1512  if (event) {
1514  }
1515  if (val_dup) {
1516  ast_free(val_dup);
1517  }
1518 
1519  return ret;
1520 }
const struct ast_calendar_tech * tech
Definition: calendar.h:118
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:293
Definition: astman.c:222
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
struct ast_calendar_event * ast_calendar_event_alloc(struct ast_calendar *cal)
Allocate an astobj2 ast_calendar_event object.
Definition: res_calendar.c:667
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const ast_string_field name
Definition: calendar.h:127
#define LOG_ERROR
Definition: logger.h:285
struct association categories[]
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
#define ast_free(a)
Definition: astmm.h:182
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...
Asterisk calendar structure.
Definition: calendar.h:117
int(* write_event)(struct ast_calendar_event *event)
Definition: calendar.h:77
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ calendarstate()

static enum ast_device_state calendarstate ( const char *  data)
static

Definition at line 381 of file res_calendar.c.

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

Referenced by load_module().

382 {
383  enum ast_device_state state;
384  struct ast_calendar *cal;
385 
386  if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) {
387  return AST_DEVICE_INVALID;
388  }
389 
390  if (cal->tech->is_busy) {
391  state = cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
392  } else {
394  }
395 
396  cal = unref_calendar(cal);
397  return state;
398 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
ast_device_state
Device States.
Definition: devicestate.h:52
const struct ast_calendar_tech * tech
Definition: calendar.h:118
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:293
#define ast_strlen_zero(foo)
Definition: strings.h:52
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:372
int(* is_busy)(struct ast_calendar *calendar)
Definition: calendar.h:74
Asterisk calendar structure.
Definition: calendar.h:117

◆ cb_pending_deletion()

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

Definition at line 1779 of file res_calendar.c.

References CMP_MATCH, and ast_calendar::pending_deletion.

Referenced by reload().

1780 {
1781  struct ast_calendar *cal = user_data;
1782 
1783  cal->pending_deletion = 1;
1784 
1785  return CMP_MATCH;
1786 }
unsigned int pending_deletion
Definition: calendar.h:137
Asterisk calendar structure.
Definition: calendar.h:117

◆ cb_rm_pending_deletion()

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

Definition at line 1788 of file res_calendar.c.

References CMP_MATCH, and ast_calendar::pending_deletion.

Referenced by reload().

1789 {
1790  struct ast_calendar *cal = user_data;
1791 
1792  return cal->pending_deletion ? CMP_MATCH : 0;
1793 }
unsigned int pending_deletion
Definition: calendar.h:137
Asterisk calendar structure.
Definition: calendar.h:117

◆ clear_events_cb()

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

Definition at line 651 of file res_calendar.c.

References CMP_MATCH, and destroy_event().

Referenced by ast_calendar_clear_events().

652 {
653  struct ast_calendar_event *event = user_data;
654 
655  event = destroy_event(event);
656 
657  return CMP_MATCH;
658 }
Definition: astman.c:222
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
Definition: res_calendar.c:626

◆ copy_event_data()

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

Definition at line 926 of file res_calendar.c.

References ast_calendar_event::alarm, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_string_field_set, ast_calendar_event::attendees, ast_calendar_event::busy_state, ast_calendar_event::categories, categories, ast_calendar_event::description, ast_calendar_event::end, ast_calendar_event::location, evententry::next, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.

Referenced by merge_events_cb().

927 {
928  struct ast_calendar_attendee *attendee;
929 
930  ast_string_field_set(dst, summary, src->summary);
931  ast_string_field_set(dst, description, src->description);
932  ast_string_field_set(dst, organizer, src->organizer);
933  ast_string_field_set(dst, location, src->location);
934  ast_string_field_set(dst, uid, src->uid);
936  dst->priority = src->priority;
937  dst->owner = src->owner;
938  dst->start = src->start;
939  dst->end = src->end;
940  dst->alarm = src->alarm;
941  dst->busy_state = src->busy_state;
942 
943  /* Delete any existing attendees */
944  while ((attendee = AST_LIST_REMOVE_HEAD(&dst->attendees, next))) {
945  ast_free(attendee);
946  }
947 
948  /* Copy over the new attendees */
949  while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) {
950  AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next);
951  }
952 }
struct ast_calendar_attendee * next
Definition: calendar.h:89
const ast_string_field uid
Definition: calendar.h:101
enum ast_calendar_busy_state busy_state
Definition: calendar.h:107
const ast_string_field description
Definition: calendar.h:101
const ast_string_field organizer
Definition: calendar.h:101
const ast_string_field location
Definition: calendar.h:101
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct association categories[]
#define ast_free(a)
Definition: astmm.h:182
struct ast_calendar * owner
Definition: calendar.h:103
const ast_string_field categories
Definition: calendar.h:101
struct ast_calendar_event::attendees attendees
const ast_string_field summary
Definition: calendar.h:101
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ destroy_event()

static struct ast_calendar_event* destroy_event ( struct ast_calendar_event event)
static

Definition at line 626 of file res_calendar.c.

References ast_debug, AST_DEVICE_BUSY, AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_sched_del(), ast_calendar_event::bs_end_sched, ast_calendar_event::bs_start_sched, calendar_is_busy(), ast_calendar::name, ast_calendar_event::notify_sched, NULL, and ast_calendar_event::owner.

Referenced by clear_events_cb(), and merge_events_cb().

627 {
628  if (event->notify_sched > -1 && ast_sched_del(sched, event->notify_sched)) {
629  ast_debug(3, "Notification running, can't delete sched entry\n");
630  }
631  if (event->bs_start_sched > -1 && ast_sched_del(sched, event->bs_start_sched)) {
632  ast_debug(3, "Devicestate update (start) running, can't delete sched entry\n");
633  }
634  if (event->bs_end_sched > -1 && ast_sched_del(sched, event->bs_end_sched)) {
635  ast_debug(3, "Devicestate update (end) running, can't delete sched entry\n");
636  }
637 
638  /* If an event is being deleted and we've fired an event changing the status at the beginning,
639  * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
640  if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
641  if (!calendar_is_busy(event->owner)) {
643  } else {
645  }
646  }
647 
648  return NULL;
649 }
Definition: sched.c:76
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
const ast_string_field name
Definition: calendar.h:127
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:372
struct ast_calendar * owner
Definition: calendar.h:103
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:610

◆ do_notify()

static void* do_notify ( void *  data)
static

Definition at line 741 of file res_calendar.c.

References ao2_ref, ast_calendar_unref_event(), ast_channel_alloc, ast_channel_context_set(), ast_channel_datastore_add(), ast_channel_exten_set(), ast_channel_lock, ast_channel_nativeformats_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, evententry::event, generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, pbx_builtin_setvar_helper(), and ast_variable::value.

Referenced by calendar_event_notify().

742 {
743  struct ast_calendar_event *event = data;
744  struct ast_dial *dial = NULL;
745  struct ast_str *apptext = NULL, *tmpstr = NULL;
746  struct ast_datastore *datastore;
747  enum ast_dial_result res;
748  struct ast_channel *chan = NULL;
749  struct ast_variable *itervar;
750  char *tech, *dest;
751  char buf[33];
752  struct ast_format_cap *caps;
753 
754  tech = ast_strdupa(event->owner->notify_channel);
755 
756  if ((dest = strchr(tech, '/'))) {
757  *dest = '\0';
758  dest++;
759  } else {
760  ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
761  goto notify_cleanup;
762  }
763 
764  if (!(dial = ast_dial_create())) {
765  ast_log(LOG_ERROR, "Could not create dial structure\n");
766  goto notify_cleanup;
767  }
768 
769  if (ast_dial_append(dial, tech, dest, NULL) < 0) {
770  ast_log(LOG_ERROR, "Could not append channel\n");
771  goto notify_cleanup;
772  }
773 
774  ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
775  generate_random_string(buf, sizeof(buf));
776 
777  if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, NULL, NULL, 0, "Calendar/%s-%s", event->owner->name, buf))) {
778  ast_log(LOG_ERROR, "Could not allocate notification channel\n");
779  goto notify_cleanup;
780  }
781 
787 
789  if (!caps) {
790  ast_log(LOG_ERROR, "Could not allocate capabilities, notification not being sent!\n");
791  goto notify_cleanup;
792  }
794  ast_channel_nativeformats_set(chan, caps);
795  ao2_ref(caps, -1);
796 
797  ast_channel_unlock(chan);
798 
799  if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) {
800  ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
801  goto notify_cleanup;
802  }
803 
804  datastore->data = event;
806 
807  ao2_ref(event, +1);
808 
809  ast_channel_lock(chan);
810  res = ast_channel_datastore_add(chan, datastore);
811  ast_channel_unlock(chan);
812 
813  if (!(tmpstr = ast_str_create(32))) {
814  goto notify_cleanup;
815  }
816 
817  for (itervar = event->owner->vars; itervar; itervar = itervar->next) {
818  ast_str_substitute_variables(&tmpstr, 0, chan, itervar->value);
819  pbx_builtin_setvar_helper(chan, itervar->name, ast_str_buffer(tmpstr));
820  }
821 
822  if (!(apptext = ast_str_create(32))) {
823  goto notify_cleanup;
824  }
825 
826  if (!ast_strlen_zero(event->owner->notify_app)) {
827  ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata);
829  } else {
830  }
831 
832  ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name);
833  res = ast_dial_run(dial, chan, 0);
834 
835  if (res != AST_DIAL_RESULT_ANSWERED) {
836  ast_verb(3, "Notification call for %s was not completed\n", event->owner->name);
837  } else {
838  struct ast_channel *answered;
839 
840  answered = ast_dial_answered_steal(dial);
841  if (ast_strlen_zero(event->owner->notify_app)) {
842  ast_channel_context_set(answered, event->owner->notify_context);
843  ast_channel_exten_set(answered, event->owner->notify_extension);
844  ast_channel_priority_set(answered, 1);
845  ast_pbx_run(answered);
846  }
847  }
848 
849 notify_cleanup:
850  if (apptext) {
851  ast_free(apptext);
852  }
853  if (tmpstr) {
854  ast_free(tmpstr);
855  }
856  if (dial) {
857  ast_dial_destroy(dial);
858  }
859  if (chan) {
860  ast_channel_release(chan);
861  }
862 
864 
865  return NULL;
866 }
struct ast_variable * next
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:717
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
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:1151
Main dialing structure. Contains global options, channels being dialed, and more! ...
Definition: dial.c:48
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
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:1313
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Definition: astman.c:222
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
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:1065
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
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:939
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
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:282
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_free(a)
Definition: astmm.h:182
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:225
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:193
unsigned int inheritance
Definition: datastore.h:73
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:993
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...
void * data
Definition: datastore.h:70
static const struct ast_channel_tech null_tech
Definition: res_calendar.c:735
void ast_channel_context_set(struct ast_channel *chan, const char *value)
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4759
static const struct ast_datastore_info event_notification_datastore
Definition: res_calendar.c:235
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ do_refresh()

static void* do_refresh ( void *  data)
static

Definition at line 1821 of file res_calendar.c.

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

Referenced by load_module().

1822 {
1823  for (;;) {
1824  struct timeval now = ast_tvnow();
1825  struct timespec ts = {0,};
1826  int wait;
1827 
1829 
1830  while (!module_unloading) {
1831  if ((wait = ast_sched_wait(sched)) < 0) {
1832  wait = 1000;
1833  }
1834 
1835  ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
1836  if (ast_cond_timedwait(&refresh_condition, &refreshlock, &ts) == ETIMEDOUT) {
1837  break;
1838  }
1839  }
1841 
1842  if (module_unloading) {
1843  break;
1844  }
1846  }
1847 
1848  return NULL;
1849 }
static ast_cond_t refresh_condition
Definition: res_calendar.c:226
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
Definition: sched.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static ast_mutex_t refreshlock
Definition: res_calendar.c:225
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:431
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define ast_mutex_unlock(a)
Definition: lock.h:188
static int module_unloading
Definition: res_calendar.c:228

◆ epoch_to_string()

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

Definition at line 1587 of file res_calendar.c.

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

Referenced by handle_show_calendar().

1588 {
1589  struct ast_tm tm;
1590  struct timeval tv = {
1591  .tv_sec = epoch,
1592  };
1593 
1594  if (!epoch) {
1595  *buf = '\0';
1596  return buf;
1597  }
1598  ast_localtime(&tv, &tm, NULL);
1599  ast_strftime(buf, buflen, "%F %r %z", &tm);
1600 
1601  return buf;
1602 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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
#define NULL
Definition: resample.c:96
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

◆ event_cmp_fn()

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

Definition at line 307 of file res_calendar.c.

References CMP_MATCH, CMP_STOP, and ast_calendar_event::uid.

Referenced by ast_calendar_event_container_alloc(), and build_calendar().

308 {
309  const struct ast_calendar_event *one = obj, *two = arg;
310  return !strcmp(one->uid, two->uid) ? CMP_MATCH | CMP_STOP : 0;
311 }
const ast_string_field uid
Definition: calendar.h:101

◆ event_hash_fn()

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

Definition at line 301 of file res_calendar.c.

References ast_str_hash().

Referenced by ast_calendar_event_container_alloc(), and build_calendar().

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

◆ event_notification_destroy()

static void event_notification_destroy ( void *  data)
static

Definition at line 695 of file res_calendar.c.

References ast_calendar_unref_event().

696 {
697  struct ast_calendar_event *event = data;
698 
700 
701 }
Definition: astman.c:222
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321

◆ event_notification_duplicate()

static void * event_notification_duplicate ( void *  data)
static

Definition at line 703 of file res_calendar.c.

References ao2_ref, evententry::event, and NULL.

704 {
705  struct ast_calendar_event *event = data;
706 
707  if (!event) {
708  return NULL;
709  }
710 
711  ao2_ref(event, +1);
712 
713  return event;
714 }
Definition: astman.c:222
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ eventlist_destroy()

static void eventlist_destroy ( void *  data)
static

Definition at line 1193 of file res_calendar.c.

References ao2_ref, and events.

1194 {
1195  struct eventlist *events = data;
1196 
1197  ao2_ref(events, -1);
1198 }
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ eventlist_destructor()

static void eventlist_destructor ( void *  obj)
static

Definition at line 347 of file res_calendar.c.

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

Referenced by calendar_query_exec().

348 {
349  struct eventlist *events = obj;
350  struct evententry *entry;
351 
352  while ((entry = AST_LIST_REMOVE_HEAD(events, list))) {
353  ao2_ref(entry->event, -1);
354  ast_free(entry);
355  }
356 }
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
struct evententry::@447 list
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_calendar_event * event
Definition: res_calendar.c:248
#define ast_free(a)
Definition: astmm.h:182
Definition: search.h:40

◆ eventlist_duplicate()

static void * eventlist_duplicate ( void *  data)
static

Definition at line 1200 of file res_calendar.c.

References ao2_ref, events, and NULL.

1201 {
1202  struct eventlist *events = data;
1203 
1204  if (!events) {
1205  return NULL;
1206  }
1207 
1208  ao2_ref(events, +1);
1209 
1210  return events;
1211 }
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ find_calendar()

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

Definition at line 293 of file res_calendar.c.

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

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

294 {
295  struct ast_calendar tmp = {
296  .name = name,
297  };
298  return ao2_find(calendars, &tmp, OBJ_POINTER);
299 }
static struct ao2_container * calendars
Definition: res_calendar.c:222
#define OBJ_POINTER
Definition: astobj2.h:1154
static int tmp()
Definition: bt_open.c:389
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
Asterisk calendar structure.
Definition: calendar.h:117

◆ find_event()

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

Definition at line 313 of file res_calendar.c.

References ao2_find, OBJ_POINTER, and ast_calendar_event::uid.

Referenced by merge_events_cb().

314 {
315  struct ast_calendar_event tmp = {
316  .uid = uid,
317  };
318  return ao2_find(events, &tmp, OBJ_POINTER);
319 }
#define OBJ_POINTER
Definition: astobj2.h:1154
static int tmp()
Definition: bt_open.c:389
const ast_string_field uid
Definition: calendar.h:101
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

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

References ast_random(), and buf.

Referenced by calendar_query_exec(), and do_notify().

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

◆ handle_dump_sched()

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

Definition at line 1690 of file res_calendar.c.

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

1691 {
1692  switch(cmd) {
1693  case CLI_INIT:
1694  e->command = "calendar dump sched";
1695  e->usage =
1696  "Usage: calendar dump sched\n"
1697  " Dump the calendar sched context";
1698  return NULL;
1699 
1700  case CLI_GENERATE:
1701  return NULL;
1702  }
1703 
1705 
1706  return CLI_SUCCESS;
1707 }
Definition: sched.c:76
Definition: cli.h:152
#define NULL
Definition: resample.c:96
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_sched_dump(struct ast_sched_context *con)
Dumps the scheduler contents.
Definition: sched.c:712

◆ handle_show_calendar()

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

Definition at line 1604 of file res_calendar.c.

References ast_calendar_event::alarm, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_calendar_unref_event(), ast_cli(), ast_strdup, ast_calendar::autoreminder, buf, ast_calendar_event::categories, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_calendar_event::description, ast_calendar_event::end, epoch_to_string(), evententry::event, ast_calendar::events, ast_cli_args::fd, find_calendar(), FORMAT, FORMAT2, ast_calendar_event::location, ast_cli_args::n, ast_calendar::name, ast_calendar::notify_app, ast_calendar::notify_appdata, ast_calendar::notify_channel, ast_calendar::notify_context, ast_calendar::notify_extension, NULL, ast_calendar_event::organizer, ast_cli_args::pos, ast_calendar_event::priority, ast_calendar::refresh, ast_calendar_event::start, ast_calendar_event::summary, ast_calendar::timeframe, ast_calendar_event::uid, unref_calendar(), ast_cli_entry::usage, and ast_cli_args::word.

1605 {
1606 #define FORMAT "%-18.18s : %-20.20s\n"
1607 #define FORMAT2 "%-12.12s: %-40.60s\n"
1608  struct ao2_iterator i;
1609  struct ast_calendar *cal;
1610  struct ast_calendar_event *event;
1611  int which = 0;
1612  char *ret = NULL;
1613 
1614  switch(cmd) {
1615  case CLI_INIT:
1616  e->command = "calendar show calendar";
1617  e->usage =
1618  "Usage: calendar show calendar <calendar name>\n"
1619  " Displays information about a calendar\n";
1620  return NULL;
1621 
1622  case CLI_GENERATE:
1623  if (a->pos != 3) {
1624  return NULL;
1625  }
1626  i = ao2_iterator_init(calendars, 0);
1627  while ((cal = ao2_iterator_next(&i))) {
1628  if (!strncasecmp(a->word, cal->name, strlen(a->word)) && ++which > a->n) {
1629  ret = ast_strdup(cal->name);
1630  cal = unref_calendar(cal);
1631  break;
1632  }
1633  cal = unref_calendar(cal);
1634  }
1636  return ret;
1637  }
1638 
1639  if (a->argc != 4) {
1640  return CLI_SHOWUSAGE;
1641  }
1642 
1643  if (!(cal = find_calendar(a->argv[3]))) {
1644  return NULL;
1645  }
1646 
1647  ast_cli(a->fd, FORMAT, "Name", cal->name);
1648  ast_cli(a->fd, FORMAT, "Notify channel", cal->notify_channel);
1649  ast_cli(a->fd, FORMAT, "Notify context", cal->notify_context);
1650  ast_cli(a->fd, FORMAT, "Notify extension", cal->notify_extension);
1651  ast_cli(a->fd, FORMAT, "Notify application", cal->notify_app);
1652  ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata);
1653  ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh);
1654  ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe);
1655 
1656  if (cal->autoreminder) {
1657  ast_cli(a->fd, "%-17.17s : %d minutes before event\n", "Autoreminder", cal->autoreminder);
1658  } else {
1659  ast_cli(a->fd, "%-17.17s : None\n", "Autoreminder");
1660  }
1661 
1662  ast_cli(a->fd, "%s\n", "Events");
1663  ast_cli(a->fd, "%s\n", "------");
1664 
1665  i = ao2_iterator_init(cal->events, 0);
1666  while ((event = ao2_iterator_next(&i))) {
1667  char buf[100];
1668 
1669  ast_cli(a->fd, FORMAT2, "Summary", event->summary);
1670  ast_cli(a->fd, FORMAT2, "Description", event->description);
1671  ast_cli(a->fd, FORMAT2, "Organizer", event->organizer);
1672  ast_cli(a->fd, FORMAT2, "Location", event->location);
1673  ast_cli(a->fd, FORMAT2, "Categories", event->categories);
1674  ast_cli(a->fd, "%-12.12s: %d\n", "Priority", event->priority);
1675  ast_cli(a->fd, FORMAT2, "UID", event->uid);
1676  ast_cli(a->fd, FORMAT2, "Start", epoch_to_string(buf, sizeof(buf), event->start));
1677  ast_cli(a->fd, FORMAT2, "End", epoch_to_string(buf, sizeof(buf), event->end));
1678  ast_cli(a->fd, FORMAT2, "Alarm", epoch_to_string(buf, sizeof(buf), event->alarm));
1679  ast_cli(a->fd, "\n");
1680 
1681  event = ast_calendar_unref_event(event);
1682  }
1684  cal = unref_calendar(cal);
1685  return CLI_SUCCESS;
1686 #undef FORMAT
1687 #undef FORMAT2
1688 }
static struct ao2_container * calendars
Definition: res_calendar.c:222
static char * epoch_to_string(char *buf, size_t buflen, time_t epoch)
#define FORMAT2
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const int argc
Definition: cli.h:160
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:293
Definition: cli.h:152
Definition: astman.c:222
const ast_string_field notify_app
Definition: calendar.h:127
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const ast_string_field uid
Definition: calendar.h:101
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
int timeframe
Definition: calendar.h:133
#define NULL
Definition: resample.c:96
const ast_string_field notify_context
Definition: calendar.h:127
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const ast_string_field description
Definition: calendar.h:101
const ast_string_field organizer
Definition: calendar.h:101
const ast_string_field location
Definition: calendar.h:101
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define FORMAT
const ast_string_field notify_appdata
Definition: calendar.h:127
const ast_string_field name
Definition: calendar.h:127
struct ao2_container * events
Definition: calendar.h:138
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const ast_string_field notify_extension
Definition: calendar.h:127
const ast_string_field categories
Definition: calendar.h:101
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const int pos
Definition: cli.h:164
Asterisk calendar structure.
Definition: calendar.h:117
int autoreminder
Definition: calendar.h:129
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321
const ast_string_field summary
Definition: calendar.h:101
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field notify_channel
Definition: calendar.h:127

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

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

1529 {
1530 #define FORMAT "%-20.20s %-10.10s %-6.6s\n"
1531  struct ao2_iterator i;
1532  struct ast_calendar *cal;
1533 
1534  switch(cmd) {
1535  case CLI_INIT:
1536  e->command = "calendar show calendars";
1537  e->usage =
1538  "Usage: calendar show calendars\n"
1539  " Lists all registered calendars.\n";
1540  return NULL;
1541  case CLI_GENERATE:
1542  return NULL;
1543  }
1544 
1545  ast_cli(a->fd, FORMAT, "Calendar", "Type", "Status");
1546  ast_cli(a->fd, FORMAT, "--------", "----", "------");
1547  i = ao2_iterator_init(calendars, 0);
1548  while ((cal = ao2_iterator_next(&i))) {
1549  ast_cli(a->fd, FORMAT, cal->name, cal->tech->type, calendar_is_busy(cal) ? "busy" : "free");
1550  cal = unref_calendar(cal);
1551  }
1553 
1554  return CLI_SUCCESS;
1555 #undef FORMAT
1556 }
const struct ast_calendar_tech * tech
Definition: calendar.h:118
static struct ao2_container * calendars
Definition: res_calendar.c:222
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * type
Definition: calendar.h:70
const int fd
Definition: cli.h:159
#define FORMAT
const ast_string_field name
Definition: calendar.h:127
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:372
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Asterisk calendar structure.
Definition: calendar.h:117
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

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

1560 {
1561 #define FORMAT "%-10.10s %-30.30s\n"
1562  struct ast_calendar_tech *iter;
1563 
1564 
1565  switch(cmd) {
1566  case CLI_INIT:
1567  e->command = "calendar show types";
1568  e->usage =
1569  "Usage: calendar show types\n"
1570  " Lists all registered calendars types.\n";
1571  return NULL;
1572  case CLI_GENERATE:
1573  return NULL;
1574  }
1575 
1576  ast_cli(a->fd, FORMAT, "Type", "Description");
1577  AST_LIST_LOCK(&techs);
1578  AST_LIST_TRAVERSE(&techs, iter, list) {
1579  ast_cli(a->fd, FORMAT, iter->type, iter->description);
1580  }
1582 
1583  return CLI_SUCCESS;
1584 #undef FORMAT
1585 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_calendar_tech::@239 list
Definition: cli.h:152
const char * description
Definition: calendar.h:71
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * type
Definition: calendar.h:70
const int fd
Definition: cli.h:159
#define FORMAT
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
Individual calendaring technology data.
Definition: calendar.h:69

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 1065 of file res_calendar.c.

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

Referenced by load_module(), and reload().

1066 {
1067  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1068  struct ast_config *tmpcfg;
1069 
1070  if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
1071  tmpcfg == CONFIG_STATUS_FILEINVALID) {
1072  ast_log(LOG_ERROR, "Unable to load config calendar.conf\n");
1073  return -1;
1074  }
1075 
1076  if (tmpcfg == CONFIG_STATUS_FILEUNCHANGED) {
1077  return 0;
1078  }
1079 
1081  if (calendar_config) {
1083  }
1084 
1085  calendar_config = tmpcfg;
1087 
1088  return 0;
1089 }
#define CONFIG_STATUS_FILEINVALID
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:3154
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_log
Definition: astobj2.c:42
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define CONFIG_STATUS_FILEUNCHANGED
#define LOG_ERROR
Definition: logger.h:285
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
static struct ast_config * calendar_config
Definition: res_calendar.c:255
static ast_rwlock_t config_lock
Definition: res_calendar.c:256
static int reload(void)

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

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_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEVSTATE_PROVIDER, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_EXTENDED, ast_mutex_init, ast_pthread_create_background, ast_sched_context_create(), ASTERISK_GPL_KEY, CALENDAR_BUCKETS, calendar_cmp_fn(), calendar_hash_fn(), calendarstate(), do_refresh(), load_config(), LOG_ERROR, NULL, refresh_condition, refresh_thread, reload(), and unload_module().

1901 {
1904  if (!calendars) {
1905  ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
1906  return AST_MODULE_LOAD_DECLINE;
1907  }
1908 
1909  if (load_config(0)) {
1910  /* We don't have calendar support enabled */
1911  return AST_MODULE_LOAD_DECLINE;
1912  }
1913 
1917 
1918  if (!(sched = ast_sched_context_create())) {
1919  ast_log(LOG_ERROR, "Unable to create sched context\n");
1922  return AST_MODULE_LOAD_DECLINE;
1923  }
1924 
1926  ast_log(LOG_ERROR, "Unable to start refresh thread--notifications disabled!\n");
1927  }
1928 
1935 
1936  ast_devstate_prov_add("Calendar", calendarstate);
1937 
1938  return AST_MODULE_LOAD_SUCCESS;
1939 }
static struct ast_custom_function calendar_busy_function
static ast_cond_t refresh_condition
Definition: res_calendar.c:226
static struct ao2_container * calendars
Definition: res_calendar.c:222
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static pthread_t refresh_thread
Definition: res_calendar.c:224
static struct ast_custom_function calendar_query_result_function
Definition: sched.c:76
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int calendar_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:281
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:391
#define NULL
Definition: resample.c:96
static struct ast_custom_function calendar_write_function
#define CALENDAR_BUCKETS
Definition: res_calendar.c:220
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_log
Definition: astobj2.c:42
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static struct ast_cli_entry calendar_cli[]
static ast_mutex_t refreshlock
Definition: res_calendar.c:225
static int calendar_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:287
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_custom_function calendar_event_function
static enum ast_device_state calendarstate(const char *data)
Definition: res_calendar.c:381
static int load_config(int reload)
static struct ast_config * calendar_config
Definition: res_calendar.c:255
static ast_mutex_t reloadlock
Definition: res_calendar.c:227
#define ast_mutex_init(pmutex)
Definition: lock.h:184
static void * do_refresh(void *data)
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
static struct ast_custom_function calendar_query_function

◆ load_tech_calendars()

static int load_tech_calendars ( struct ast_calendar_tech tech)
static

Definition at line 513 of file res_calendar.c.

References ast_calendar_unregister(), ast_category_browse(), ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, ast_variable_retrieve(), build_calendar(), config_lock, LOG_WARNING, NULL, ast_calendar_tech::type, and unref_calendar().

Referenced by ast_calendar_register(), and reload().

514 {
515  struct ast_calendar *cal;
516  const char *cat = NULL;
517  const char *val;
518 
519  if (!calendar_config) {
520  ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
521  return -1;
522  }
523 
525  while ((cat = ast_category_browse(calendar_config, cat))) {
526  if (!strcasecmp(cat, "general")) {
527  continue;
528  }
529 
530  if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) {
531  continue;
532  }
533 
534  /* A serious error occurred loading calendars from this tech and it should be disabled */
535  if (!(cal = build_calendar(calendar_config, cat, tech))) {
538  return -1;
539  }
540 
541  cal = unref_calendar(cal);
542  }
543 
545 
546  return 0;
547 }
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:274
static struct ast_calendar * build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech)
Definition: res_calendar.c:400
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
Definition: res_calendar.c:587
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
const char * type
Definition: calendar.h:70
#define ast_log
Definition: astobj2.c:42
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:275
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
static struct ast_config * calendar_config
Definition: res_calendar.c:255
Asterisk calendar structure.
Definition: calendar.h:117
static ast_rwlock_t config_lock
Definition: res_calendar.c:256

◆ match_caltech_cb()

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

Definition at line 575 of file res_calendar.c.

References CMP_MATCH, and ast_calendar::tech.

Referenced by ast_calendar_unregister().

576 {
577  struct ast_calendar *cal = user_data;
578  struct ast_calendar_tech *tech = arg;
579 
580  if (cal->tech == tech) {
581  return CMP_MATCH;
582  }
583 
584  return 0;
585 }
const struct ast_calendar_tech * tech
Definition: calendar.h:118
Individual calendaring technology data.
Definition: calendar.h:69
Asterisk calendar structure.
Definition: calendar.h:117

◆ merge_events_cb()

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

Definition at line 1016 of file res_calendar.c.

References ao2_unlink, ast_calendar_unref_event(), CMP_MATCH, copy_event_data(), destroy_event(), find_event(), ast_calendar_event::owner, schedule_calendar_event(), and ast_calendar_event::uid.

Referenced by ast_calendar_merge_events().

1017 {
1018  struct ast_calendar_event *old_event = obj, *new_event;
1019  struct ao2_container *new_events = arg;
1020 
1021  /* If we don't find the old_event in new_events, then we can safely delete the old_event */
1022  if (!(new_event = find_event(new_events, old_event->uid))) {
1023  old_event = destroy_event(old_event);
1024  return CMP_MATCH;
1025  }
1026 
1027  /* We have events to merge. If any data that will affect a scheduler event has changed,
1028  * then we need to replace the scheduler event */
1029  schedule_calendar_event(old_event->owner, old_event, new_event);
1030 
1031  /* Since we don't want to mess with cancelling sched events and adding new ones, just
1032  * copy the internals of the new_event to the old_event */
1033  copy_event_data(old_event, new_event);
1034 
1035  /* Now we can go ahead and unlink the new_event from new_events and unref it so that only completely
1036  * new events remain in the container */
1037  ao2_unlink(new_events, new_event);
1038  new_event = ast_calendar_unref_event(new_event);
1039 
1040  return 0;
1041 }
const ast_string_field uid
Definition: calendar.h:101
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:954
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
Definition: res_calendar.c:626
static void copy_event_data(struct ast_calendar_event *dst, struct ast_calendar_event *src)
Definition: res_calendar.c:926
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
struct ast_calendar * owner
Definition: calendar.h:103
static struct ast_calendar_event * find_event(struct ao2_container *events, const char *uid)
Definition: res_calendar.c:313
Generic container type.
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:321

◆ null_chan_write()

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

Definition at line 730 of file res_calendar.c.

731 {
732  return 0;
733 }

◆ reload()

static int reload ( void  )
static

Definition at line 1795 of file res_calendar.c.

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

Referenced by load_module().

1796 {
1797  struct ast_calendar_tech *iter;
1798 
1800 
1801  /* Mark existing calendars for deletion */
1803  load_config(1);
1804 
1805  AST_LIST_LOCK(&techs);
1806  AST_LIST_TRAVERSE(&techs, iter, list) {
1807  if (load_tech_calendars(iter)) {
1808  ast_log(LOG_WARNING, "Failed to reload %s calendars, module disabled\n", iter->type);
1809  }
1810  }
1812 
1813  /* Delete calendars that no longer show up in the config */
1815 
1817 
1818  return 0;
1819 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ao2_container * calendars
Definition: res_calendar.c:222
static int load_tech_calendars(struct ast_calendar_tech *tech)
Definition: res_calendar.c:513
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ast_calendar_tech::@239 list
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
const char * type
Definition: calendar.h:70
#define ast_log
Definition: astobj2.c:42
static int cb_pending_deletion(void *user_data, void *arg, int flags)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int load_config(int reload)
Individual calendaring technology data.
Definition: calendar.h:69
static ast_mutex_t reloadlock
Definition: res_calendar.c:227
#define ast_mutex_unlock(a)
Definition: lock.h:188
static int cb_rm_pending_deletion(void *user_data, void *arg, int flags)

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

References ast_calendar_event::alarm, ao2_lock, ao2_unlock, ast_cond_signal, ast_debug, ast_mutex_lock, ast_mutex_unlock, AST_SCHED_REPLACE, ast_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, evententry::event, ast_calendar::notify_channel, ast_calendar_event::notify_sched, refresh_condition, and ast_calendar_event::start.

Referenced by add_new_event_cb(), and merge_events_cb().

955 {
956  struct timeval now = ast_tvnow();
957  struct ast_calendar_event *event;
958  time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end;
959  int changed = 0;
960 
961  event = cmp_event ? cmp_event : old_event;
962 
963  ao2_lock(event);
964  if (!ast_strlen_zero(cal->notify_channel) && (!cmp_event || old_event->alarm != event->alarm)) {
965  changed = 1;
966  if (cal->autoreminder) {
967  alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000;
968  } else if (event->alarm) {
969  alarm_notify_sched = (event->alarm - now.tv_sec) * 1000;
970  }
971 
972  /* For now, send the notification if we missed it, but the meeting hasn't happened yet */
973  if (event->start >= now.tv_sec) {
974  if (alarm_notify_sched <= 0) {
975  alarm_notify_sched = 1;
976  }
978  AST_SCHED_REPLACE(old_event->notify_sched, sched, alarm_notify_sched, calendar_event_notify, old_event);
980  ast_debug(3, "Calendar alarm event notification scheduled to happen in %ld ms\n", (long) alarm_notify_sched);
981  }
982  }
983 
984  if (!cmp_event || old_event->start != event->start) {
985  changed = 1;
986  devstate_sched_start = (event->start - now.tv_sec) * 1000;
987 
988  if (devstate_sched_start < 1) {
989  devstate_sched_start = 1;
990  }
991 
993  AST_SCHED_REPLACE(old_event->bs_start_sched, sched, devstate_sched_start, calendar_devstate_change, old_event);
995  ast_debug(3, "Calendar bs_start event notification scheduled to happen in %ld ms\n", (long) devstate_sched_start);
996  }
997 
998  if (!cmp_event || old_event->end != event->end) {
999  changed = 1;
1000  devstate_sched_end = (event->end - now.tv_sec) * 1000;
1002  AST_SCHED_REPLACE(old_event->bs_end_sched, sched, devstate_sched_end, calendar_devstate_change, old_event);
1004  ast_debug(3, "Calendar bs_end event notification scheduled to happen in %ld ms\n", (long) devstate_sched_end);
1005  }
1006 
1007  if (changed) {
1009  }
1010 
1011  ao2_unlock(event);
1012 
1013  return 0;
1014 }
static int calendar_devstate_change(const void *data)
Definition: res_calendar.c:892
static ast_cond_t refresh_condition
Definition: res_calendar.c:226
static int calendar_event_notify(const void *data)
Definition: res_calendar.c:868
#define AST_SCHED_REPLACE(id, sched, when, callback, data)
Definition: sched.h:125
Definition: sched.c:76
Definition: astman.c:222
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_lock(a)
Definition: astobj2.h:718
static ast_mutex_t refreshlock
Definition: res_calendar.c:225
int autoreminder
Definition: calendar.h:129
const ast_string_field notify_channel
Definition: calendar.h:127
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1852 of file res_calendar.c.

References ao2_callback, ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), ast_cond_signal, ast_config_destroy(), ast_custom_function_unregister(), ast_devstate_prov_del(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_sched_context_destroy(), ast_unload_resource(), evententry::list, ast_calendar_tech::module, module_unloading, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, refresh_condition, and refresh_thread.

Referenced by load_module().

1853 {
1854  struct ast_calendar_tech *tech;
1855 
1856  ast_devstate_prov_del("calendar");
1863 
1864  /* Remove all calendars */
1867  calendars = NULL;
1868 
1870  module_unloading = 1;
1873  pthread_join(refresh_thread, NULL);
1874 
1876 
1877  AST_LIST_LOCK(&techs);
1879  ast_unload_resource(tech->module, 0);
1880  }
1883 
1886 
1887  return 0;
1888 }
static struct ast_custom_function calendar_busy_function
static ast_cond_t refresh_condition
Definition: res_calendar.c:226
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ao2_container * calendars
Definition: res_calendar.c:222
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static pthread_t refresh_thread
Definition: res_calendar.c:224
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static struct ast_custom_function calendar_query_result_function
struct ast_calendar_tech::@239 list
Definition: sched.c:76
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418
const char * module
Definition: calendar.h:72
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct ast_custom_function calendar_write_function
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_cond_signal(cond)
Definition: lock.h:201
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static struct ast_cli_entry calendar_cli[]
static ast_mutex_t refreshlock
Definition: res_calendar.c:225
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1229
static struct ast_custom_function calendar_event_function
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ast_config * calendar_config
Definition: res_calendar.c:255
Individual calendaring technology data.
Definition: calendar.h:69
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269
static struct ast_custom_function calendar_query_function
#define ast_mutex_unlock(a)
Definition: lock.h:188
static int module_unloading
Definition: res_calendar.c:228

◆ unref_calendar()

static struct ast_calendar* unref_calendar ( struct ast_calendar cal)
static

Definition at line 275 of file res_calendar.c.

References ao2_ref, and NULL.

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

276 {
277  ao2_ref(cal, -1);
278  return NULL;
279 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
static

Definition at line 1946 of file res_calendar.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

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

◆ calendar_cli

struct ast_cli_entry calendar_cli[]
static

Definition at line 1709 of file res_calendar.c.

◆ calendar_config

struct ast_config* calendar_config
static

Definition at line 255 of file res_calendar.c.

Referenced by ast_calendar_config_acquire().

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

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

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

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

◆ calendars

struct ao2_container* calendars
static

Definition at line 222 of file res_calendar.c.

◆ 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:703
static void event_notification_destroy(void *data)
Definition: res_calendar.c:695

Definition at line 235 of file res_calendar.c.

◆ 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_destroy(void *data)
static void * eventlist_duplicate(void *data)

Definition at line 241 of file res_calendar.c.

◆ module_unloading

int module_unloading
static

Definition at line 228 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:730

Definition at line 735 of file res_calendar.c.

◆ refresh_condition

ast_cond_t refresh_condition
static

Definition at line 226 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 224 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 227 of file res_calendar.c.

◆ sched

struct ast_sched_context* sched
static

Definition at line 223 of file res_calendar.c.

◆ techs

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