Wed Jan 8 2020 09:50:18

Asterisk developer's documentation


res_calendar.c File Reference

Calendaring API. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/calendar.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/channel.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/sched.h"
#include "asterisk/dial.h"
#include "asterisk/cli.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"

Go to the source code of this file.

Data Structures

struct  evententry
 
struct  eventlist
 
struct  techs
 

Macros

#define CALENDAR_BUCKETS   19
 
#define FORMAT   "%-20.20s %-10.10s %-6.6s\n"
 
#define FORMAT   "%-17.17s : %-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...
 
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...
 
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 int load_config (int reload)
 
static int load_module (void)
 
static int load_tech_calendars (struct ast_calendar_tech *tech)
 
static int match_caltech_cb (void *user_data, void *arg, int flags)
 
static int merge_events_cb (void *obj, void *arg, int flags)
 
static int null_chan_write (struct ast_channel *chan, struct ast_frame *frame)
 
static int reload (void)
 
static int schedule_calendar_event (struct ast_calendar *cal, struct ast_calendar_event *old_event, struct ast_calendar_event *cmp_event)
 
static int unload_module (void)
 
static struct ast_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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
 
static 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 }
 
static struct ast_datastore_info event_notification_datastore
 
static struct ast_datastore_info eventlist_datastore_info
 
static int module_unloading
 
static struct ast_channel_tech null_tech
 
static ast_cond_t refresh_condition
 
static pthread_t refresh_thread = AST_PTHREADT_NULL
 
static ast_mutex_t refreshlock
 
static ast_mutex_t reloadlock
 
static struct sched_contextsched
 
static struct techs techs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 

Detailed Description

Calendaring API.

Todo:

Support responding to a meeting invite

Support writing attendees

Definition in file res_calendar.c.

Macro Definition Documentation

#define CALENDAR_BUCKETS   19

Definition at line 199 of file res_calendar.c.

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

#define FORMAT   "%-20.20s %-10.10s %-6.6s\n"
#define FORMAT   "%-17.17s : %-20.20s\n"
#define FORMAT2   "%-12.12s: %-40.60s\n"

Referenced by handle_show_calendar().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 1794 of file res_calendar.c.

static void __unreg_module ( void  )
static

Definition at line 1794 of file res_calendar.c.

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

Definition at line 1027 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().

1028 {
1029  struct evententry *entry, *iter;
1030  int event_startdiff = abs(start - event->start);
1031  int event_enddiff = abs(end - event->end);
1032  int i = 0;
1033 
1034  if (!(entry = ast_calloc(1, sizeof(*entry)))) {
1035  ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1036  return -1;
1037  }
1038 
1039  entry->event = event;
1040  ao2_ref(event, +1);
1041 
1042  if (start == end) {
1043  AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) {
1044  int startdiff = abs(iter->event->start - start);
1045 
1046  ast_debug(10, "Comparing %s with startdiff %d to %s with startdiff %d\n", event->summary, event_startdiff, iter->event->summary, startdiff);
1047  ++i;
1048  if (startdiff > event_startdiff) {
1050  return i;
1051  }
1052  if (startdiff == event_startdiff) {
1053  int enddiff = abs(iter->event->end - end);
1054 
1055  if (enddiff > event_enddiff) {
1057  return i;
1058  }
1059  if (event_startdiff == enddiff) {
1060  if (strcmp(event->uid, iter->event->uid) < 0) {
1062  return i;
1063  }
1064  }
1065  }
1066  }
1068 
1069  AST_LIST_INSERT_TAIL(events, entry, list);
1070 
1071  return i;
1072  }
1073 
1074  AST_LIST_TRAVERSE_SAFE_BEGIN(events, iter, list) {
1075  ++i;
1076  if (iter->event->start > event->start) {
1078  return i;
1079  }
1080 
1081  if (iter->event->start == event->start) {
1082  if ((iter->event->end - iter->event->start) == (event->end - event->start)) {
1083  if (strcmp(event->uid, iter->event->uid) < 0) {
1085  return i;
1086  }
1087  }
1088  if ((iter->event->end - iter->event->start) < (event->end - event->start)) {
1090  return i;
1091  }
1092  }
1093  }
1095 
1096  AST_LIST_INSERT_TAIL(events, entry, list);
1097 
1098  return i;
1099 }
const ast_string_field uid
Definition: calendar.h:101
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct evententry::@323 list
struct ast_calendar_event * event
Definition: res_calendar.c:227
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_calloc(a, b)
Definition: astmm.h:82
#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:584
const ast_string_field summary
Definition: calendar.h:101
static int add_new_event_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 951 of file res_calendar.c.

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

Referenced by ast_calendar_merge_events().

952 {
953  struct ast_calendar_event *new_event = obj;
954  struct ao2_container *events = arg;
955 
956  ao2_link(events, new_event);
957  schedule_calendar_event(new_event->owner, new_event, NULL);
958  return CMP_MATCH;
959 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
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:862
struct ast_calendar * owner
Definition: calendar.h:103
static struct adsi_event events[]
Definition: app_adsiprog.c:78
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 596 of file res_calendar.c.

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

Referenced by calendar_destructor().

597 {
598  ast_debug(3, "Clearing all events for calendar %s\n", cal->name);
599 
601 }
static int clear_events_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:587
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: calendar.h:127
struct ao2_container * events
Definition: calendar.h:136
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 237 of file res_calendar.c.

References ast_rwlock_rdlock, ast_rwlock_unlock, and calendar_config.

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

238 {
240 
241  if (!calendar_config) {
243  return NULL;
244  }
245 
246  return calendar_config;
247 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:201
#define ast_rwlock_unlock(a)
Definition: lock.h:200
static struct ast_config * calendar_config
Definition: res_calendar.c:234
static ast_rwlock_t config_lock
Definition: res_calendar.c:235
void ast_calendar_config_release ( void  )

Release the calendar config.

Definition at line 249 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().

250 {
252 }
#define ast_rwlock_unlock(a)
Definition: lock.h:200
static ast_rwlock_t config_lock
Definition: res_calendar.c:235
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 603 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(), and evententry::event.

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

604 {
605  struct ast_calendar_event *event;
606  if (!(event = ao2_alloc(sizeof(*event), calendar_event_destructor))) {
607  return NULL;
608  }
609 
610  if (ast_string_field_init(event, 32)) {
611  event = ast_calendar_unref_event(event);
612  return NULL;
613  }
614 
615  event->owner = cal;
616  event->notify_sched = -1;
617  event->bs_start_sched = -1;
618  event->bs_end_sched = -1;
619 
621 
622  return event;
623 }
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static void calendar_event_destructor(void *obj)
Definition: res_calendar.c:545
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
struct ast_calendar_event::attendees attendees
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
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 625 of file res_calendar.c.

References ao2_container_alloc, CALENDAR_BUCKETS, event_cmp_fn(), and event_hash_fn().

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

626 {
628 }
static int event_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:280
#define CALENDAR_BUCKETS
Definition: res_calendar.c:199
static int event_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:286
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
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 961 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().

962 {
963  /* Loop through all events attached to the calendar. If there is a matching new event
964  * merge its data over and handle any schedule changes that need to be made. Then remove
965  * the new_event from new_events so that we are left with only new_events that we can add later. */
967 
968  /* Now, we should only have completely new events in new_events. Loop through and add them */
970 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
struct ao2_container * events
Definition: calendar.h:136
static int merge_events_cb(void *obj, void *arg, int flags)
Definition: res_calendar.c:924
static int add_new_event_cb(void *obj, void *arg, int flags)
Definition: res_calendar.c:951
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 490 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, ast_calendar_tech::type, and ast_calendar_tech::user.

Referenced by load_module().

491 {
492  struct ast_calendar_tech *iter;
493 
495  AST_LIST_TRAVERSE(&techs, iter, list) {
496  if(!strcasecmp(tech->type, iter->type)) {
497  ast_log(LOG_WARNING, "Already have a handler for calendar type '%s'\n", tech->type);
499  return -1;
500  }
501  }
503  tech->user = ast_module_user_add(NULL);
505 
506  ast_verb(2, "Registered calendar type '%s' (%s)\n", tech->type, tech->description);
507 
508  return load_tech_calendars(tech);
509 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_calendar_tech::@145 list
static int load_tech_calendars(struct ast_calendar_tech *tech)
Definition: res_calendar.c:454
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_module_user * user
Definition: calendar.h:73
const char * description
Definition: calendar.h:71
#define ast_verb(level,...)
Definition: logger.h:243
const char * type
Definition: calendar.h:70
#define ast_module_user_add(chan)
Definition: module.h:268
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:696
Individual calendaring technology data.
Definition: calendar.h:69
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 300 of file res_calendar.c.

References ao2_ref.

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

301 {
302  ao2_ref(event, -1);
303  return NULL;
304 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
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 523 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().

524 {
525  struct ast_calendar_tech *iter;
526 
529  if (iter != tech) {
530  continue;
531  }
532 
534 
537  ast_verb(2, "Unregistered calendar type '%s'\n", tech->type);
538  break;
539  }
542 
543 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ao2_container * calendars
Definition: res_calendar.c:201
struct ast_calendar_tech::@145 list
#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:910
struct ast_module_user * user
Definition: calendar.h:73
#define ast_module_user_remove(user)
Definition: module.h:269
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_verb(level,...)
Definition: logger.h:243
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:554
static int match_caltech_cb(void *user_data, void *arg, int flags)
Definition: res_calendar.c:511
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
static struct ast_calendar* build_calendar ( struct ast_config cfg,
const char *  cat,
const struct ast_calendar_tech tech 
)
static

Definition at line 378 of file res_calendar.c.

References ao2_alloc, ao2_container_alloc, ao2_link, ao2_unlink, ast_cond_init, ast_log(), ast_pthread_create, AST_PTHREADT_NULL, ast_string_field_init, ast_string_field_set, ast_variable_browse(), ast_calendar::autoreminder, CALENDAR_BUCKETS, calendar_destructor(), event_cmp_fn(), event_hash_fn(), ast_calendar::events, find_calendar(), ast_calendar_tech::load_calendar, LOG_ERROR, name, ast_variable::name, ast_variable::next, ast_calendar::notify_waittime, ast_calendar::pending_deletion, ast_calendar::refresh, ast_calendar::tech, ast_calendar::thread, ast_calendar::timeframe, ast_calendar::unload, unref_calendar(), and ast_variable::value.

Referenced by load_tech_calendars().

379 {
380  struct ast_calendar *cal;
381  struct ast_variable *v;
382  int new_calendar = 0;
383 
384  if (!(cal = find_calendar(cat))) {
385  new_calendar = 1;
386  if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) {
387  ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n");
388  return NULL;
389  }
390 
392  ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat);
393  cal = unref_calendar(cal);
394  return NULL;
395  }
396 
397  if (ast_string_field_init(cal, 32)) {
398  ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat);
399  cal = unref_calendar(cal);
400  return NULL;
401  }
402  } else {
403  cal->pending_deletion = 0;
404  }
405 
406  ast_string_field_set(cal, name, cat);
407  cal->tech = tech;
408 
409  cal->refresh = 3600;
410  cal->timeframe = 60;
411  cal->notify_waittime = 30000;
412 
413  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
414  if (!strcasecmp(v->name, "autoreminder")) {
415  cal->autoreminder = atoi(v->value);
416  } else if (!strcasecmp(v->name, "channel")) {
417  ast_string_field_set(cal, notify_channel, v->value);
418  } else if (!strcasecmp(v->name, "context")) {
419  ast_string_field_set(cal, notify_context, v->value);
420  } else if (!strcasecmp(v->name, "extension")) {
421  ast_string_field_set(cal, notify_extension, v->value);
422  } else if (!strcasecmp(v->name, "waittime")) {
423  int i = atoi(v->value);
424  if (i > 0) {
425  cal->notify_waittime = 1000 * i;
426  }
427  } else if (!strcasecmp(v->name, "app")) {
428  ast_string_field_set(cal, notify_app, v->value);
429  } else if (!strcasecmp(v->name, "appdata")) {
430  ast_string_field_set(cal, notify_appdata, v->value);
431  } else if (!strcasecmp(v->name, "refresh")) {
432  cal->refresh = atoi(v->value);
433  } else if (!strcasecmp(v->name, "timeframe")) {
434  cal->timeframe = atoi(v->value);
435  }
436  }
437 
438  if (new_calendar) {
439  cal->thread = AST_PTHREADT_NULL;
440  ast_cond_init(&cal->unload, NULL);
441  ao2_link(calendars, cal);
442  if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) {
443  /* If we start failing to create threads, go ahead and return NULL
444  * and the tech module will be unregistered
445  */
446  ao2_unlink(calendars, cal);
447  cal = unref_calendar(cal);
448  }
449  }
450 
451  return cal;
452 }
ast_cond_t unload
Definition: calendar.h:133
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
static struct ao2_container * calendars
Definition: res_calendar.c:201
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:272
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static int event_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:280
#define ast_cond_init(cond, attr)
Definition: lock.h:167
int notify_waittime
Definition: calendar.h:129
int timeframe
Definition: calendar.h:131
#define CALENDAR_BUCKETS
Definition: res_calendar.c:199
const char * value
Definition: config.h:79
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
#define AST_PTHREADT_NULL
Definition: lock.h:65
const char * name
Definition: config.h:77
static void calendar_destructor(void *obj)
Definition: res_calendar.c:306
struct ast_calendar_tech * tech
Definition: calendar.h:118
struct ao2_container * events
Definition: calendar.h:136
pthread_t thread
Definition: calendar.h:132
#define LOG_ERROR
Definition: logger.h:155
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
static const char name[]
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:418
void *(* load_calendar)(void *data)
Definition: calendar.h:75
static int event_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:286
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
int pending_deletion
Definition: calendar.h:135
struct ast_variable * next
Definition: config.h:82
Asterisk calendar structure.
Definition: calendar.h:117
int autoreminder
Definition: calendar.h:128
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static int calendar_busy_callback ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 336 of file res_calendar.c.

References AST_CALENDAR_BS_FREE, ast_tvnow(), ast_calendar_event::busy_state, CMP_STOP, ast_calendar_event::end, evententry::event, and ast_calendar_event::start.

Referenced by calendar_is_busy().

337 {
338  struct ast_calendar_event *event = obj;
339  int *is_busy = arg;
340  struct timeval tv = ast_tvnow();
341 
342  if (tv.tv_sec >= event->start && tv.tv_sec <= event->end && event->busy_state > AST_CALENDAR_BS_FREE) {
343  *is_busy = 1;
344  return CMP_STOP;
345  }
346 
347  return 0;
348 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct timeval tv
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 1000 of file res_calendar.c.

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

1001 {
1002  struct ast_calendar *cal;
1003 
1004  if (ast_strlen_zero(data)) {
1005  ast_log(LOG_WARNING, "CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n");
1006  return -1;
1007  }
1008 
1009  cal = find_calendar(data);
1010 
1011  if (!cal) {
1012  ast_log(LOG_WARNING, "Could not find calendar '%s'\n", data);
1013  return -1;
1014  }
1015 
1016  strcpy(buf, calendar_is_busy(cal) ? "1" : "0");
1017  cal = unref_calendar(cal);
1018 
1019  return 0;
1020 }
#define LOG_WARNING
Definition: logger.h:144
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:272
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:350
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Asterisk calendar structure.
Definition: calendar.h:117
static int calendar_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 266 of file res_calendar.c.

References CMP_MATCH, CMP_STOP, and ast_calendar::name.

Referenced by load_module().

267 {
268  const struct ast_calendar *one = obj, *two = arg;
269  return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP: 0;
270 }
const ast_string_field name
Definition: calendar.h:127
Asterisk calendar structure.
Definition: calendar.h:117
static void calendar_destructor ( void *  obj)
static

Definition at line 306 of file res_calendar.c.

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

Referenced by build_calendar().

307 {
308  struct ast_calendar *cal = obj;
309 
310  ast_debug(3, "Destroying calendar %s\n", cal->name);
311 
312  ao2_lock(cal);
313  cal->unloading = 1;
314  ast_cond_signal(&cal->unload);
315  pthread_join(cal->thread, NULL);
316  if (cal->tech_pvt) {
317  cal->tech_pvt = cal->tech->unref_calendar(cal->tech_pvt);
318  }
321  ao2_ref(cal->events, -1);
322  ao2_unlock(cal);
323 }
ast_cond_t unload
Definition: calendar.h:133
int unloading
Definition: calendar.h:134
void *(* unref_calendar)(void *obj)
Definition: calendar.h:76
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_cond_signal(cond)
Definition: lock.h:169
void ast_calendar_clear_events(struct ast_calendar *cal)
Remove all events from calendar.
Definition: res_calendar.c:596
void * tech_pvt
Definition: calendar.h:119
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
struct ast_calendar_tech * tech
Definition: calendar.h:118
const ast_string_field name
Definition: calendar.h:127
struct ao2_container * events
Definition: calendar.h:136
pthread_t thread
Definition: calendar.h:132
Asterisk calendar structure.
Definition: calendar.h:117
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int calendar_devstate_change ( const void *  data)
static

Definition at line 800 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(), evententry::event, LOG_WARNING, ast_calendar::name, and ast_calendar_event::owner.

Referenced by schedule_calendar_event().

801 {
802  struct ast_calendar_event *event = (struct ast_calendar_event *)data;
803  struct timeval now = ast_tvnow();
804  int is_end_event;
805 
806  if (!event) {
807  ast_log(LOG_WARNING, "Event was NULL!\n");
808  return 0;
809  }
810 
811  ao2_ref(event, +1);
812 
813  is_end_event = event->end <= now.tv_sec;
814 
815  if (is_end_event) {
816  event->bs_end_sched = -1;
817  } else {
818  event->bs_start_sched = -1;
819  }
820 
821  /* We can have overlapping events, so ignore the event->busy_state and check busy state
822  * based on all events in the calendar */
823  if (!calendar_is_busy(event->owner)) {
824  ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
825  } else {
826  ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
827  }
828 
829  event = ast_calendar_unref_event(event);
830 
831  return 0;
832 }
#define LOG_WARNING
Definition: logger.h:144
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
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:516
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:350
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
static void calendar_event_destructor ( void *  obj)
static

Definition at line 545 of file res_calendar.c.

References ast_debug, ast_free, AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_calendar_event::attendees, ast_calendar_attendee::data, evententry::event, ast_calendar::name, evententry::next, and ast_calendar_event::owner.

Referenced by ast_calendar_event_alloc().

546 {
547  struct ast_calendar_event *event = obj;
548  struct ast_calendar_attendee *attendee;
549 
550  ast_debug(3, "Destroying event for calendar '%s'\n", event->owner->name);
552  while ((attendee = AST_LIST_REMOVE_HEAD(&event->attendees, next))) {
553  if (attendee->data) {
554  ast_free(attendee->data);
555  }
556  ast_free(attendee);
557  }
558 }
struct ast_calendar_attendee * next
Definition: calendar.h:89
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
#define ast_free(a)
Definition: astmm.h:97
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int calendar_event_notify ( const void *  data)
static

Definition at line 776 of file res_calendar.c.

References ao2_ref, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, do_notify(), evententry::event, LOG_ERROR, and ast_calendar_event::owner.

Referenced by schedule_calendar_event().

777 {
778  struct ast_calendar_event *event = (void *)data;
779  int res = -1;
780  pthread_t notify_thread = AST_PTHREADT_NULL;
781 
782  if (!(event && event->owner)) {
783  ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
784  return res;
785  }
786 
787  ao2_ref(event, +1);
788  event->notify_sched = -1;
789 
790  if (ast_pthread_create_background(&notify_thread, NULL, do_notify, event) < 0) {
791  ast_log(LOG_ERROR, "Could not create notification thread\n");
792  return res;
793  }
794 
795  res = 0;
796 
797  return res;
798 }
static void * do_notify(void *data)
Definition: res_calendar.c:676
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int calendar_event_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1583 of file res_calendar.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_calendar_event::busy_state, calendar_join_attendees(), ast_calendar_event::categories, ast_datastore::data, ast_calendar_event::description, ast_calendar_event::end, evententry::event, ast_calendar_event::location, LOG_WARNING, ast_calendar::name, ast_channel::name, ast_calendar_event::organizer, ast_calendar_event::owner, ast_calendar_event::priority, ast_calendar_event::start, ast_calendar_event::summary, and ast_calendar_event::uid.

1584 {
1585  struct ast_datastore *datastore;
1586  struct ast_calendar_event *event;
1587 
1588  if (!chan) {
1589  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
1590  return -1;
1591  }
1592 
1593  if (ast_strlen_zero(data)) {
1594  ast_log(LOG_WARNING, "%s requires an argument\n", cmd);
1595  return -1;
1596  }
1597 
1598  ast_channel_lock(chan);
1599  if (!(datastore = ast_channel_datastore_find(chan, &event_notification_datastore, NULL))) {
1600  ast_log(LOG_WARNING, "There is no event notification datastore on '%s'!\n", chan->name);
1601  ast_channel_unlock(chan);
1602  return -1;
1603  }
1604  ast_channel_unlock(chan);
1605 
1606  if (!(event = datastore->data)) {
1607  ast_log(LOG_WARNING, "The datastore contains no data!\n");
1608  return -1;
1609  }
1610 
1611  if (!strcasecmp(data, "summary")) {
1612  ast_copy_string(buf, event->summary, len);
1613  } else if (!strcasecmp(data, "description")) {
1614  ast_copy_string(buf, event->description, len);
1615  } else if (!strcasecmp(data, "organizer")) {
1616  ast_copy_string(buf, event->organizer, len);
1617  } else if (!strcasecmp(data, "location")) {
1618  ast_copy_string(buf, event->location, len);
1619  } else if (!strcasecmp(data, "categories")) {
1620  ast_copy_string(buf, event->categories, len);
1621  } else if (!strcasecmp(data, "priority")) {
1622  snprintf(buf, len, "%d", event->priority);
1623  } else if (!strcasecmp(data, "calendar")) {
1624  ast_copy_string(buf, event->owner->name, len);
1625  } else if (!strcasecmp(data, "uid")) {
1626  ast_copy_string(buf, event->uid, len);
1627  } else if (!strcasecmp(data, "start")) {
1628  snprintf(buf, len, "%ld", (long)event->start);
1629  } else if (!strcasecmp(data, "end")) {
1630  snprintf(buf, len, "%ld", (long)event->end);
1631  } else if (!strcasecmp(data, "busystate")) {
1632  snprintf(buf, len, "%u", event->busy_state);
1633  } else if (!strcasecmp(data, "attendees")) {
1634  calendar_join_attendees(event, buf, len);
1635  }
1636 
1637 
1638  return 0;
1639 }
static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define LOG_WARNING
Definition: logger.h:144
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:54
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:2604
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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)
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_calendar * owner
Definition: calendar.h:103
const ast_string_field categories
Definition: calendar.h:101
void * data
Definition: datastore.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static struct ast_datastore_info event_notification_datastore
Definition: res_calendar.c:214
const ast_string_field summary
Definition: calendar.h:101
static int calendar_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 260 of file res_calendar.c.

References ast_str_case_hash(), and ast_calendar::name.

Referenced by load_module().

261 {
262  const struct ast_calendar *cal = obj;
263  return ast_str_case_hash(cal->name);
264 }
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:989
static int calendar_is_busy ( struct ast_calendar cal)
static

Definition at line 350 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().

351 {
352  int is_busy = 0;
353 
355 
356  return is_busy;
357 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
static int calendar_busy_callback(void *obj, void *arg, int flags)
Definition: res_calendar.c:336
struct ao2_container * events
Definition: calendar.h:136
static void calendar_join_attendees ( struct ast_calendar_event event,
char *  buf,
size_t  len 
)
static

Definition at line 1212 of file res_calendar.c.

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

Referenced by calendar_event_read(), and calendar_query_result_exec().

1213 {
1214  struct ast_str *tmp;
1215  struct ast_calendar_attendee *attendee;
1216 
1217  if (!(tmp = ast_str_create(32))) {
1218  ast_log(LOG_ERROR, "Could not allocate memory for attendees!\n");
1219  return;
1220  }
1221 
1222  AST_LIST_TRAVERSE(&event->attendees, attendee, next) {
1223  ast_str_append(&tmp, 0, "%s%s", attendee == AST_LIST_FIRST(&event->attendees) ? "" : ",", attendee->data);
1224  }
1225 
1226  ast_copy_string(buf, ast_str_buffer(tmp), len);
1227  ast_free(tmp);
1228 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:97
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:223
static int calendar_query_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1121 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, 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().

1122 {
1123  struct ast_calendar *cal;
1124  struct ao2_iterator i;
1125  struct ast_calendar_event *event;
1126  struct eventlist *events;
1127  time_t start = INT_MIN, end = INT_MAX;
1128  struct ast_datastore *eventlist_datastore;
1130  AST_APP_ARG(calendar);
1131  AST_APP_ARG(start);
1132  AST_APP_ARG(end);
1133  );
1134 
1135  if (!chan) {
1136  ast_log(LOG_WARNING, "%s requires a channel to store the data on\n", cmd);
1137  return -1;
1138  }
1139 
1141 
1142  if (ast_strlen_zero(args.calendar)) {
1143  ast_log(LOG_WARNING, "%s requires a calendar argument\n", cmd);
1144  return -1;
1145  }
1146 
1147  if (!(cal = find_calendar(args.calendar))) {
1148  ast_log(LOG_WARNING, "Unknown calendar '%s'\n", args.calendar);
1149  return -1;
1150  }
1151 
1152  if (!(events = ao2_alloc(sizeof(*events), eventlist_destructor))) {
1153  ast_log(LOG_ERROR, "Unable to allocate memory for event list\n");
1154  cal = unref_calendar(cal);
1155  return -1;
1156  }
1157 
1158  if (!ast_strlen_zero(args.start)) {
1159  start = atoi(args.start);
1160  }
1161 
1162  if (!ast_strlen_zero(args.end)) {
1163  end = atoi(args.end);
1164  }
1165 
1166  i = ao2_iterator_init(cal->events, 0);
1167  while ((event = ao2_iterator_next(&i))) {
1168  if (!(start > event->end || end < event->start)) {
1169  ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end);
1170  if (add_event_to_list(events, event, start, end) < 0) {
1171  event = ast_calendar_unref_event(event);
1172  cal = unref_calendar(cal);
1173  ao2_ref(events, -1);
1175  return -1;
1176  }
1177  }
1178 
1179  event = ast_calendar_unref_event(event);
1180  }
1182 
1183  ast_channel_lock(chan);
1184  do {
1187  ast_channel_unlock(chan);
1188 
1189  if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) {
1190  ast_log(LOG_ERROR, "Could not allocate datastore!\n");
1191  cal = unref_calendar(cal);
1192  ao2_ref(events, -1);
1193  return -1;
1194  }
1195 
1196  eventlist_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1197  eventlist_datastore->data = events;
1198 
1199  ast_channel_lock(chan);
1200  ast_channel_datastore_add(chan, eventlist_datastore);
1201  ast_channel_unlock(chan);
1202 
1203  cal = unref_calendar(cal);
1204  return 0;
1205 }
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:652
#define ast_channel_lock(chan)
Definition: channel.h:2466
static struct ast_datastore_info eventlist_datastore_info
Definition: res_calendar.c:220
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define LOG_WARNING
Definition: logger.h:144
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:272
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
Structure for a data store object.
Definition: datastore.h:54
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:2604
static void eventlist_destructor(void *obj)
Definition: res_calendar.c:325
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct ao2_container * events
Definition: calendar.h:136
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
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:254
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:156
unsigned int inheritance
Definition: datastore.h:58
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
void * data
Definition: datastore.h:56
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
static struct adsi_event events[]
Definition: app_adsiprog.c:78
Asterisk calendar structure.
Definition: calendar.h:117
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
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:2590
static int calendar_query_result_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1230 of file res_calendar.c.

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

1231 {
1232  struct ast_datastore *datastore;
1233  struct eventlist *events;
1234  struct evententry *entry;
1235  int row = 1;
1236  size_t listlen = 0;
1238  AST_APP_ARG(id);
1239  AST_APP_ARG(field);
1240  AST_APP_ARG(row);
1241  );
1242 
1243  if (!chan) {
1244  ast_log(LOG_WARNING, "%s requires a channel\n", cmd);
1245  return -1;
1246  }
1247 
1248  AST_STANDARD_APP_ARGS(args, data);
1249 
1250  if (ast_strlen_zero(args.id) || ast_strlen_zero(args.field)) {
1251  ast_log(LOG_WARNING, "%s requires an id and a field", cmd);
1252  return -1;
1253  }
1254 
1255  ast_channel_lock(chan);
1256  if (!(datastore = ast_channel_datastore_find(chan, &eventlist_datastore_info, args.id))) {
1257  ast_log(LOG_WARNING, "There is no event notification datastore with id '%s' on '%s'!\n", args.id, chan->name);
1258  ast_channel_unlock(chan);
1259  return -1;
1260  }
1261  ast_channel_unlock(chan);
1262 
1263  if (!(events = datastore->data)) {
1264  ast_log(LOG_WARNING, "The datastore contains no data!\n");
1265  return -1;
1266  }
1267 
1268  if (!ast_strlen_zero(args.row)) {
1269  row = atoi(args.row);
1270  }
1271 
1272  AST_LIST_TRAVERSE(events, entry, list) {
1273  listlen++;
1274  }
1275 
1276  if (!strcasecmp(args.field, "getnum")) {
1277  snprintf(buf, len, "%zu", listlen);
1278  return 0;
1279  }
1280 
1281  AST_LIST_TRAVERSE(events, entry, list) {
1282  if (--row) {
1283  continue;
1284  }
1285  if (!strcasecmp(args.field, "summary")) {
1286  ast_copy_string(buf, entry->event->summary, len);
1287  } else if (!strcasecmp(args.field, "description")) {
1288  ast_copy_string(buf, entry->event->description, len);
1289  } else if (!strcasecmp(args.field, "organizer")) {
1290  ast_copy_string(buf, entry->event->organizer, len);
1291  } else if (!strcasecmp(args.field, "location")) {
1292  ast_copy_string(buf, entry->event->location, len);
1293  } else if (!strcasecmp(args.field, "categories")) {
1294  ast_copy_string(buf, entry->event->categories, len);
1295  } else if (!strcasecmp(args.field, "priority")) {
1296  snprintf(buf, len, "%d", entry->event->priority);
1297  } else if (!strcasecmp(args.field, "calendar")) {
1298  ast_copy_string(buf, entry->event->owner->name, len);
1299  } else if (!strcasecmp(args.field, "uid")) {
1300  ast_copy_string(buf, entry->event->uid, len);
1301  } else if (!strcasecmp(args.field, "start")) {
1302  snprintf(buf, len, "%ld", (long) entry->event->start);
1303  } else if (!strcasecmp(args.field, "end")) {
1304  snprintf(buf, len, "%ld", (long) entry->event->end);
1305  } else if (!strcasecmp(args.field, "busystate")) {
1306  snprintf(buf, len, "%u", entry->event->busy_state);
1307  } else if (!strcasecmp(args.field, "attendees")) {
1308  calendar_join_attendees(entry->event, buf, len);
1309  } else {
1310  ast_log(LOG_WARNING, "Unknown field '%s'\n", args.field);
1311  }
1312  break;
1313  }
1314 
1315  return 0;
1316 }
static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
#define ast_channel_lock(chan)
Definition: channel.h:2466
static struct ast_datastore_info eventlist_datastore_info
Definition: res_calendar.c:220
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
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:54
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:2604
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct evententry::@323 list
const ast_string_field name
Definition: calendar.h:127
struct ast_calendar_event * event
Definition: res_calendar.c:227
static struct @350 args
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:2467
struct ast_calendar * owner
Definition: calendar.h:103
const ast_string_field categories
Definition: calendar.h:101
void * data
Definition: datastore.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
static struct adsi_event events[]
Definition: app_adsiprog.c:78
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
const ast_string_field summary
Definition: calendar.h:101
static int calendar_write_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 1323 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(), ast_calendar_event::end, evententry::event, find_calendar(), LOG_ERROR, LOG_WARNING, ast_calendar::name, ast_calendar_event::start, ast_calendar::tech, unref_calendar(), and ast_calendar_tech::write_event.

1324 {
1325  int i, j, ret = -1;
1326  char *val_dup = NULL;
1327  struct ast_calendar *cal = NULL;
1328  struct ast_calendar_event *event = NULL;
1329  struct timeval tv = ast_tvnow();
1330  AST_DECLARE_APP_ARGS(fields,
1331  AST_APP_ARG(field)[10];
1332  );
1334  AST_APP_ARG(value)[10];
1335  );
1336 
1337  if (!(val_dup = ast_strdup(value))) {
1338  ast_log(LOG_ERROR, "Could not allocate memory for values\n");
1339  return -1;
1340  }
1341 
1342  AST_STANDARD_APP_ARGS(fields, data);
1343  AST_STANDARD_APP_ARGS(values, val_dup);
1344 
1345  /* XXX Eventually we will support unnamed calendars, so if we don't find one, we parse
1346  * for a calendar type and create it */
1347  if (!(cal = find_calendar(fields.field[0]))) {
1348  ast_log(LOG_WARNING, "Couldn't find calendar '%s'\n", fields.field[0]);
1349  goto write_cleanup;
1350  }
1351 
1352  if (!(cal->tech->write_event)) {
1353  ast_log(LOG_WARNING, "Calendar '%s' has no write function!\n", cal->name);
1354  goto write_cleanup;
1355  }
1356 
1357  if (!(event = ast_calendar_event_alloc(cal))) {
1358  goto write_cleanup;
1359  }
1360 
1361  if (ast_strlen_zero(fields.field[0])) {
1362  ast_log(LOG_WARNING, "CALENDAR_WRITE requires a calendar name!\n");
1363  goto write_cleanup;
1364  }
1365 
1366  if (fields.argc - 1 != values.argc) {
1367  ast_log(LOG_WARNING, "CALENDAR_WRITE should have the same number of fields (%u) and values (%u)!\n", fields.argc - 1, values.argc);
1368  goto write_cleanup;
1369  }
1370 
1371  event->owner = cal;
1372 
1373  for (i = 1, j = 0; i < fields.argc; i++, j++) {
1374  if (!strcasecmp(fields.field[i], "summary")) {
1375  ast_string_field_set(event, summary, values.value[j]);
1376  } else if (!strcasecmp(fields.field[i], "description")) {
1377  ast_string_field_set(event, description, values.value[j]);
1378  } else if (!strcasecmp(fields.field[i], "organizer")) {
1379  ast_string_field_set(event, organizer, values.value[j]);
1380  } else if (!strcasecmp(fields.field[i], "location")) {
1381  ast_string_field_set(event, location, values.value[j]);
1382  } else if (!strcasecmp(fields.field[i], "categories")) {
1383  ast_string_field_set(event, categories, values.value[j]);
1384  } else if (!strcasecmp(fields.field[i], "priority")) {
1385  event->priority = atoi(values.value[j]);
1386  } else if (!strcasecmp(fields.field[i], "uid")) {
1387  ast_string_field_set(event, uid, values.value[j]);
1388  } else if (!strcasecmp(fields.field[i], "start")) {
1389  event->start = atoi(values.value[j]);
1390  } else if (!strcasecmp(fields.field[i], "end")) {
1391  event->end = atoi(values.value[j]);
1392  } else if (!strcasecmp(fields.field[i], "busystate")) {
1393  event->busy_state = atoi(values.value[j]);
1394  } else {
1395  ast_log(LOG_WARNING, "Unknown calendar event field '%s'\n", fields.field[i]);
1396  }
1397  }
1398 
1399  if (!event->start) {
1400  event->start = tv.tv_sec;
1401  }
1402 
1403  if (!event->end) {
1404  event->end = tv.tv_sec;
1405  }
1406 
1407  if((ret = cal->tech->write_event(event))) {
1408  ast_log(LOG_WARNING, "Writing event to calendar '%s' failed!\n", cal->name);
1409  }
1410 
1411 write_cleanup:
1412  if (cal) {
1413  cal = unref_calendar(cal);
1414  }
1415  if (event) {
1416  event = ast_calendar_unref_event(event);
1417  }
1418  if (val_dup) {
1419  ast_free(val_dup);
1420  }
1421 
1422  return ret;
1423 }
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:272
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int value
Definition: syslog.c:39
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_calendar_tech * tech
Definition: calendar.h:118
const ast_string_field name
Definition: calendar.h:127
struct ast_calendar_event * ast_calendar_event_alloc(struct ast_calendar *cal)
Allocate an astobj2 ast_calendar_event object.
Definition: res_calendar.c:603
#define LOG_ERROR
Definition: logger.h:155
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int(* write_event)(struct ast_calendar_event *event)
Definition: calendar.h:77
#define ast_free(a)
Definition: astmm.h:97
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
struct timeval tv
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
Asterisk calendar structure.
Definition: calendar.h:117
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static enum ast_device_state calendarstate ( const char *  data)
static

Definition at line 359 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().

360 {
361  enum ast_device_state state;
362  struct ast_calendar *cal;
363 
364  if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) {
365  return AST_DEVICE_INVALID;
366  }
367 
368  if (cal->tech->is_busy) {
369  state = cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
370  } else {
372  }
373 
374  cal = unref_calendar(cal);
375  return state;
376 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
ast_device_state
Device States.
Definition: devicestate.h:51
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:272
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_calendar_tech * tech
Definition: calendar.h:118
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:350
int(* is_busy)(struct ast_calendar *calendar)
Definition: calendar.h:74
Asterisk calendar structure.
Definition: calendar.h:117
static int cb_pending_deletion ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 1646 of file res_calendar.c.

References CMP_MATCH, and ast_calendar::pending_deletion.

Referenced by reload().

1647 {
1648  struct ast_calendar *cal = user_data;
1649 
1650  cal->pending_deletion = 1;
1651 
1652  return CMP_MATCH;
1653 }
int pending_deletion
Definition: calendar.h:135
Asterisk calendar structure.
Definition: calendar.h:117
static int cb_rm_pending_deletion ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 1655 of file res_calendar.c.

References CMP_MATCH, and ast_calendar::pending_deletion.

Referenced by reload().

1656 {
1657  struct ast_calendar *cal = user_data;
1658 
1659  return cal->pending_deletion ? CMP_MATCH : 0;
1660 }
int pending_deletion
Definition: calendar.h:135
Asterisk calendar structure.
Definition: calendar.h:117
static int clear_events_cb ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 587 of file res_calendar.c.

References CMP_MATCH, destroy_event(), and evententry::event.

Referenced by ast_calendar_clear_events().

588 {
589  struct ast_calendar_event *event = user_data;
590 
591  event = destroy_event(event);
592 
593  return CMP_MATCH;
594 }
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
Definition: res_calendar.c:562
static void copy_event_data ( struct ast_calendar_event dst,
struct ast_calendar_event src 
)
static

Definition at line 834 of file res_calendar.c.

References ast_calendar_event::alarm, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_string_field_set, ast_calendar_event::attendees, ast_calendar_event::busy_state, ast_calendar_event::categories, ast_calendar_event::description, ast_calendar_event::end, ast_calendar_event::location, 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().

835 {
836  struct ast_calendar_attendee *attendee;
837 
838  ast_string_field_set(dst, summary, src->summary);
839  ast_string_field_set(dst, description, src->description);
840  ast_string_field_set(dst, organizer, src->organizer);
841  ast_string_field_set(dst, location, src->location);
842  ast_string_field_set(dst, uid, src->uid);
843  ast_string_field_set(dst, categories, src->categories);
844  dst->priority = src->priority;
845  dst->owner = src->owner;
846  dst->start = src->start;
847  dst->end = src->end;
848  dst->alarm = src->alarm;
849  dst->busy_state = src->busy_state;
850 
851  /* Delete any existing attendees */
852  while ((attendee = AST_LIST_REMOVE_HEAD(&dst->attendees, next))) {
853  ast_free(attendee);
854  }
855 
856  /* Copy over the new attendees */
857  while ((attendee = AST_LIST_REMOVE_HEAD(&src->attendees, next))) {
858  AST_LIST_INSERT_TAIL(&dst->attendees, attendee, next);
859  }
860 }
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:818
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
#define ast_free(a)
Definition: astmm.h:97
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:344
static struct ast_calendar_event* destroy_event ( struct ast_calendar_event event)
static

Definition at line 562 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, and ast_calendar_event::owner.

Referenced by clear_events_cb(), and merge_events_cb().

563 {
564  if (event->notify_sched > -1 && ast_sched_del(sched, event->notify_sched)) {
565  ast_debug(3, "Notification running, can't delete sched entry\n");
566  }
567  if (event->bs_start_sched > -1 && ast_sched_del(sched, event->bs_start_sched)) {
568  ast_debug(3, "Devicestate update (start) running, can't delete sched entry\n");
569  }
570  if (event->bs_end_sched > -1 && ast_sched_del(sched, event->bs_end_sched)) {
571  ast_debug(3, "Devicestate update (end) running, can't delete sched entry\n");
572  }
573 
574  /* If an event is being deleted and we've fired an event changing the status at the beginning,
575  * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
576  if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
577  if (!calendar_is_busy(event->owner)) {
579  } else {
581  }
582  }
583 
584  return NULL;
585 }
int ast_sched_del(struct sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event Remove this event from being run. A procedure should not remove its own eve...
Definition: sched.c:468
Definition: sched.c:57
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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:516
const ast_string_field name
Definition: calendar.h:127
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:350
struct ast_calendar * owner
Definition: calendar.h:103
static void* do_notify ( void *  data)
static

Definition at line 676 of file res_calendar.c.

References ao2_ref, ast_calendar_unref_event(), ast_channel_alloc(), ast_channel_datastore_add(), ast_channel_lock, ast_channel_release(), ast_channel_unlock, ast_copy_string(), ast_datastore_alloc(), ast_dial_answered_steal(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), AST_DIAL_OPTION_ANSWER_EXEC, ast_dial_option_global_enable(), AST_DIAL_RESULT_ANSWERED, ast_dial_run(), ast_dial_set_global_timeout(), AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_pbx_run(), AST_STATE_DOWN, ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_verb, ast_channel::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, evententry::event, ast_channel::exten, generate_random_string(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_calendar::name, ast_channel::nativeformats, ast_calendar::notify_app, ast_calendar::notify_appdata, ast_calendar::notify_channel, ast_calendar::notify_context, ast_calendar::notify_extension, ast_calendar::notify_waittime, null_tech, ast_calendar_event::owner, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::tech, and ast_channel::writeformat.

Referenced by calendar_event_notify().

677 {
678  struct ast_calendar_event *event = data;
679  struct ast_dial *dial = NULL;
680  struct ast_str *apptext = NULL;
681  struct ast_datastore *datastore;
682  enum ast_dial_result res;
683  struct ast_channel *chan = NULL;
684  char *tech, *dest;
685  char buf[8];
686 
687  tech = ast_strdupa(event->owner->notify_channel);
688 
689  if ((dest = strchr(tech, '/'))) {
690  *dest = '\0';
691  dest++;
692  } else {
693  ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
694  goto notify_cleanup;
695  }
696 
697  if (!(dial = ast_dial_create())) {
698  ast_log(LOG_ERROR, "Could not create dial structure\n");
699  goto notify_cleanup;
700  }
701 
702  if (ast_dial_append(dial, tech, dest) < 0) {
703  ast_log(LOG_ERROR, "Could not append channel\n");
704  goto notify_cleanup;
705  }
706 
707  ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
708  generate_random_string(buf, sizeof(buf));
709 
710  if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "Calendar/%s-%s", event->owner->name, buf))) {
711  ast_log(LOG_ERROR, "Could not allocate notification channel\n");
712  goto notify_cleanup;
713  }
714 
715  chan->tech = &null_tech;
716  chan->nativeformats = chan->writeformat = chan->rawwriteformat =
718 
719  if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) {
720  ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
721  goto notify_cleanup;
722  }
723 
724  datastore->data = event;
726 
727  ao2_ref(event, +1);
728 
729  ast_channel_lock(chan);
730  res = ast_channel_datastore_add(chan, datastore);
731  ast_channel_unlock(chan);
732 
733  if (!(apptext = ast_str_create(32))) {
734  goto notify_cleanup;
735  }
736 
737  if (!ast_strlen_zero(event->owner->notify_app)) {
738  ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata);
740  } else {
741  }
742 
743  ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name);
744  res = ast_dial_run(dial, chan, 0);
745 
746  if (res != AST_DIAL_RESULT_ANSWERED) {
747  ast_verb(3, "Notification call for %s was not completed\n", event->owner->name);
748  } else {
749  struct ast_channel *answered;
750 
751  answered = ast_dial_answered_steal(dial);
752  if (ast_strlen_zero(event->owner->notify_app)) {
753  ast_copy_string(answered->context, event->owner->notify_context, sizeof(answered->context));
754  ast_copy_string(answered->exten, event->owner->notify_extension, sizeof(answered->exten));
755  answered->priority = 1;
756  ast_pbx_run(answered);
757  }
758  }
759 
760 notify_cleanup:
761  if (apptext) {
762  ast_free(apptext);
763  }
764  if (dial) {
765  ast_dial_destroy(dial);
766  }
767  if (chan) {
768  ast_channel_release(chan);
769  }
770 
771  event = ast_calendar_unref_event(event);
772 
773  return NULL;
774 }
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
Definition: res_calendar.c:652
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
Enables an option globally.
Definition: dial.c:923
int priority
Definition: channel.h:841
Main dialing structure. Contains global options, channels being dialed, and more! ...
Definition: dial.c:47
format_t writeformat
Definition: channel.h:854
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:1053
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1921
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
Append a channel.
Definition: dial.c:229
format_t rawwriteformat
Definition: channel.h:856
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
format_t nativeformats
Definition: channel.h:852
Structure for a data store object.
Definition: datastore.h:54
format_t rawreadformat
Definition: channel.h:855
#define ast_verb(level,...)
Definition: logger.h:243
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
static struct ast_channel_tech null_tech
Definition: res_calendar.c:670
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:874
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:48
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
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:714
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:201
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:156
unsigned int inheritance
Definition: datastore.h:58
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:766
void * data
Definition: datastore.h:56
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
format_t readformat
Definition: channel.h:853
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:5926
static struct ast_datastore_info event_notification_datastore
Definition: res_calendar.c:214
struct ast_channel_tech * tech
Definition: channel.h:743
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static void* do_refresh ( void *  data)
static

Definition at line 1688 of file res_calendar.c.

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

Referenced by load_module().

1689 {
1690  for (;;) {
1691  struct timeval now = ast_tvnow();
1692  struct timespec ts = {0,};
1693  int wait;
1694 
1696 
1697  while (!module_unloading) {
1698  if ((wait = ast_sched_wait(sched)) < 0) {
1699  wait = 1000;
1700  }
1701 
1702  ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
1703  if (ast_cond_timedwait(&refresh_condition, &refreshlock, &ts) == ETIMEDOUT) {
1704  break;
1705  }
1706  }
1708 
1709  if (module_unloading) {
1710  break;
1711  }
1713  }
1714 
1715  return NULL;
1716 }
static ast_cond_t refresh_condition
Definition: res_calendar.c:205
Definition: sched.c:57
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t refreshlock
Definition: res_calendar.c:204
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int module_unloading
Definition: res_calendar.c:207
static char* epoch_to_string ( char *  buf,
size_t  buflen,
time_t  epoch 
)
static

Definition at line 1461 of file res_calendar.c.

References ast_localtime(), and ast_strftime().

Referenced by handle_show_calendar().

1462 {
1463  struct ast_tm tm;
1464  struct timeval tv = {
1465  .tv_sec = epoch,
1466  };
1467 
1468  if (!epoch) {
1469  *buf = '\0';
1470  return buf;
1471  }
1472  ast_localtime(&tv, &tm, NULL);
1473  ast_strftime(buf, buflen, "%F %r %z", &tm);
1474 
1475  return buf;
1476 }
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:1570
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:2351
struct timeval tv
static int event_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 286 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().

287 {
288  const struct ast_calendar_event *one = obj, *two = arg;
289  return !strcmp(one->uid, two->uid) ? CMP_MATCH | CMP_STOP : 0;
290 }
const ast_string_field uid
Definition: calendar.h:101
static int event_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 280 of file res_calendar.c.

References ast_str_hash(), evententry::event, and ast_calendar_event::uid.

Referenced by ast_calendar_event_container_alloc(), and build_calendar().

281 {
282  const struct ast_calendar_event *event = obj;
283  return ast_str_hash(event->uid);
284 }
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:949
static void event_notification_destroy ( void *  data)
static

Definition at line 630 of file res_calendar.c.

References ast_calendar_unref_event(), and evententry::event.

631 {
632  struct ast_calendar_event *event = data;
633 
634  event = ast_calendar_unref_event(event);
635 
636 }
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
static void * event_notification_duplicate ( void *  data)
static

Definition at line 638 of file res_calendar.c.

References ao2_ref, and evententry::event.

639 {
640  struct ast_calendar_event *event = data;
641 
642  if (!event) {
643  return NULL;
644  }
645 
646  ao2_ref(event, +1);
647 
648  return event;
649 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void eventlist_destroy ( void *  data)
static

Definition at line 1101 of file res_calendar.c.

References ao2_ref, and events.

1102 {
1103  struct eventlist *events = data;
1104 
1105  ao2_ref(events, -1);
1106 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct adsi_event events[]
Definition: app_adsiprog.c:78
static void eventlist_destructor ( void *  obj)
static

Definition at line 325 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().

326 {
327  struct eventlist *events = obj;
328  struct evententry *entry;
329 
330  while ((entry = AST_LIST_REMOVE_HEAD(events, list))) {
331  ao2_ref(entry->event, -1);
332  ast_free(entry);
333  }
334 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct evententry::@323 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct ast_calendar_event * event
Definition: res_calendar.c:227
#define ast_free(a)
Definition: astmm.h:97
static struct adsi_event events[]
Definition: app_adsiprog.c:78
static void * eventlist_duplicate ( void *  data)
static

Definition at line 1108 of file res_calendar.c.

References ao2_ref, and events.

1109 {
1110  struct eventlist *events = data;
1111 
1112  if (!events) {
1113  return NULL;
1114  }
1115 
1116  ao2_ref(events, +1);
1117 
1118  return events;
1119 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct adsi_event events[]
Definition: app_adsiprog.c:78
static struct ast_calendar* find_calendar ( const char *  name)
static

Definition at line 272 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().

273 {
274  struct ast_calendar tmp = {
275  .name = name,
276  };
277  return ao2_find(calendars, &tmp, OBJ_POINTER);
278 }
static struct ao2_container * calendars
Definition: res_calendar.c:201
const ast_string_field name
Definition: calendar.h:127
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static const char name[]
Asterisk calendar structure.
Definition: calendar.h:117
static struct ast_calendar_event* find_event ( struct ao2_container events,
const char *  uid 
)
static

Definition at line 292 of file res_calendar.c.

References ao2_find, OBJ_POINTER, and ast_calendar_event::uid.

Referenced by merge_events_cb().

293 {
294  struct ast_calendar_event tmp = {
295  .uid = uid,
296  };
297  return ao2_find(events, &tmp, OBJ_POINTER);
298 }
const ast_string_field uid
Definition: calendar.h:101
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static char* generate_random_string ( char *  buf,
size_t  size 
)
static

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

Definition at line 652 of file res_calendar.c.

References ast_random().

Referenced by calendar_query_exec(), and do_notify().

653 {
654  unsigned long val[4];
655  int x;
656 
657  for (x = 0; x < 4; x++) {
658  val[x] = ast_random();
659  }
660  snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
661 
662  return buf;
663 }
Definition: ast_expr2.c:325
long int ast_random(void)
Definition: utils.c:1640
static char* handle_dump_sched ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1558 of file res_calendar.c.

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

1559 {
1560  switch(cmd) {
1561  case CLI_INIT:
1562  e->command = "calendar dump sched";
1563  e->usage =
1564  "Usage: calendar dump sched\n"
1565  " Dump the calendar sched context";
1566  return NULL;
1567 
1568  case CLI_GENERATE:
1569  return NULL;
1570  }
1571 
1573 
1574  return CLI_SUCCESS;
1575 }
void ast_sched_dump(struct sched_context *con)
Dumps the scheduler contents Debugging: Dump the contents of the scheduler to stderr.
Definition: sched.c:565
Definition: sched.c:57
Definition: cli.h:146
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_show_calendar ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1478 of file res_calendar.c.

References ast_calendar_event::alarm, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_calendar_unref_event(), ast_cli(), ast_strdup, ast_calendar::autoreminder, ast_calendar_event::categories, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_calendar_event::description, ast_calendar_event::end, epoch_to_string(), 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, 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.

1479 {
1480 #define FORMAT "%-17.17s : %-20.20s\n"
1481 #define FORMAT2 "%-12.12s: %-40.60s\n"
1482  struct ao2_iterator i;
1483  struct ast_calendar *cal;
1484  struct ast_calendar_event *event;
1485  int which = 0;
1486  char *ret = NULL;
1487 
1488  switch(cmd) {
1489  case CLI_INIT:
1490  e->command = "calendar show calendar";
1491  e->usage =
1492  "Usage: calendar show calendar <calendar name>\n"
1493  " Displays information about a calendar\n";
1494  return NULL;
1495 
1496  case CLI_GENERATE:
1497  if (a->pos != 3) {
1498  return NULL;
1499  }
1500  i = ao2_iterator_init(calendars, 0);
1501  while ((cal = ao2_iterator_next(&i))) {
1502  if (!strncasecmp(a->word, cal->name, strlen(a->word)) && ++which > a->n) {
1503  ret = ast_strdup(cal->name);
1504  cal = unref_calendar(cal);
1505  break;
1506  }
1507  cal = unref_calendar(cal);
1508  }
1510  return ret;
1511  }
1512 
1513  if (a->argc != 4) {
1514  return CLI_SHOWUSAGE;
1515  }
1516 
1517  if (!(cal = find_calendar(a->argv[3]))) {
1518  return NULL;
1519  }
1520 
1521  ast_cli(a->fd, FORMAT, "Name", cal->name);
1522  ast_cli(a->fd, FORMAT, "Notify channel", cal->notify_channel);
1523  ast_cli(a->fd, FORMAT, "Notify context", cal->notify_context);
1524  ast_cli(a->fd, FORMAT, "Notify extension", cal->notify_extension);
1525  ast_cli(a->fd, FORMAT, "Notify application", cal->notify_app);
1526  ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata);
1527  ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh);
1528  ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe);
1529  ast_cli(a->fd, "%-17.17s : %d\n", "Autoreminder", cal->autoreminder);
1530  ast_cli(a->fd, "%s\n", "Events");
1531  ast_cli(a->fd, "%s\n", "------");
1532 
1533  i = ao2_iterator_init(cal->events, 0);
1534  while ((event = ao2_iterator_next(&i))) {
1535  char buf[100];
1536 
1537  ast_cli(a->fd, FORMAT2, "Summary", event->summary);
1538  ast_cli(a->fd, FORMAT2, "Description", event->description);
1539  ast_cli(a->fd, FORMAT2, "Organizer", event->organizer);
1540  ast_cli(a->fd, FORMAT2, "Location", event->location);
1541  ast_cli(a->fd, FORMAT2, "Categories", event->categories);
1542  ast_cli(a->fd, "%-12.12s: %d\n", "Priority", event->priority);
1543  ast_cli(a->fd, FORMAT2, "UID", event->uid);
1544  ast_cli(a->fd, FORMAT2, "Start", epoch_to_string(buf, sizeof(buf), event->start));
1545  ast_cli(a->fd, FORMAT2, "End", epoch_to_string(buf, sizeof(buf), event->end));
1546  ast_cli(a->fd, FORMAT2, "Alarm", epoch_to_string(buf, sizeof(buf), event->alarm));
1547  ast_cli(a->fd, "\n");
1548 
1549  event = ast_calendar_unref_event(event);
1550  }
1552  cal = unref_calendar(cal);
1553  return CLI_SUCCESS;
1554 #undef FORMAT
1555 #undef FORMAT2
1556 }
#define FORMAT
static struct ao2_container * calendars
Definition: res_calendar.c:201
static char * epoch_to_string(char *buf, size_t buflen, time_t epoch)
#define ast_strdup(a)
Definition: astmm.h:109
#define FORMAT2
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
const int argc
Definition: cli.h:154
static struct ast_calendar * find_calendar(const char *name)
Definition: res_calendar.c:272
Definition: cli.h:146
const ast_string_field notify_app
Definition: calendar.h:127
const ast_string_field uid
Definition: calendar.h:101
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
int timeframe
Definition: calendar.h:131
const ast_string_field notify_context
Definition: calendar.h:127
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
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:153
const int n
Definition: cli.h:159
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:136
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const ast_string_field notify_extension
Definition: calendar.h:127
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const ast_string_field categories
Definition: calendar.h:101
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
const int pos
Definition: cli.h:158
Asterisk calendar structure.
Definition: calendar.h:117
int autoreminder
Definition: calendar.h:128
const ast_string_field summary
Definition: calendar.h:101
const ast_string_field notify_channel
Definition: calendar.h:127
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 1431 of file res_calendar.c.

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

1432 {
1433 #define FORMAT "%-20.20s %-10.10s %-6.6s\n"
1434  struct ao2_iterator i;
1435  struct ast_calendar *cal;
1436 
1437  switch(cmd) {
1438  case CLI_INIT:
1439  e->command = "calendar show calendars";
1440  e->usage =
1441  "Usage: calendar show calendars\n"
1442  " Lists all registered calendars.\n";
1443  return NULL;
1444  case CLI_GENERATE:
1445  return NULL;
1446  }
1447 
1448  ast_cli(a->fd, FORMAT, "Calendar", "Type", "Status");
1449  ast_cli(a->fd, FORMAT, "--------", "----", "------");
1450  i = ao2_iterator_init(calendars, 0);
1451  while ((cal = ao2_iterator_next(&i))) {
1452  ast_cli(a->fd, FORMAT, cal->name, cal->tech->type, calendar_is_busy(cal) ? "busy" : "free");
1453  cal = unref_calendar(cal);
1454  }
1456 
1457  return CLI_SUCCESS;
1458 #undef FORMAT
1459 }
#define FORMAT
static struct ao2_container * calendars
Definition: res_calendar.c:201
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
Definition: cli.h:146
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * type
Definition: calendar.h:70
const int fd
Definition: cli.h:153
struct ast_calendar_tech * tech
Definition: calendar.h:118
const ast_string_field name
Definition: calendar.h:127
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
static int calendar_is_busy(struct ast_calendar *cal)
Definition: res_calendar.c:350
char * command
Definition: cli.h:180
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
Asterisk calendar structure.
Definition: calendar.h:117
static int load_config ( int  reload)
static

Definition at line 973 of file res_calendar.c.

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

Referenced by load_module(), and reload().

974 {
975  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
976  struct ast_config *tmpcfg;
977 
978  if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
979  tmpcfg == CONFIG_STATUS_FILEINVALID) {
980  ast_log(LOG_ERROR, "Unable to load config calendar.conf\n");
981  return -1;
982  }
983 
984  if (tmpcfg == CONFIG_STATUS_FILEUNCHANGED) {
985  return 0;
986  }
987 
989  if (calendar_config) {
991  }
992 
993  calendar_config = tmpcfg;
995 
996  return 0;
997 }
#define ast_rwlock_unlock(a)
Definition: lock.h:200
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_rwlock_wrlock(a)
Definition: lock.h:202
static struct ast_config * calendar_config
Definition: res_calendar.c:234
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static ast_rwlock_t config_lock
Definition: res_calendar.c:235
static int reload(void)
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int load_module ( void  )
static

Definition at line 1753 of file res_calendar.c.

References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_cond_init, ast_custom_function_register, ast_devstate_prov_add(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_pthread_create_background, CALENDAR_BUCKETS, calendar_busy_function, calendar_cli, calendar_cmp_fn(), calendar_event_function, calendar_hash_fn(), calendar_query_function, calendar_query_result_function, calendar_write_function, calendarstate(), do_refresh(), load_config(), LOG_ERROR, and sched_context_create().

1754 {
1756  ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
1757  return AST_MODULE_LOAD_FAILURE;
1758  }
1759 
1760  if (load_config(0)) {
1761  /* We don't have calendar support enabled */
1762  return AST_MODULE_LOAD_DECLINE;
1763  }
1764 
1768 
1769  if (!(sched = sched_context_create())) {
1770  ast_log(LOG_ERROR, "Unable to create sched context\n");
1771  return AST_MODULE_LOAD_FAILURE;
1772  }
1773 
1774  if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
1775  ast_log(LOG_ERROR, "Unable to start refresh thread--notifications disabled!\n");
1776  }
1777 
1784 
1785  ast_devstate_prov_add("Calendar", calendarstate);
1786 
1787  return AST_MODULE_LOAD_SUCCESS;
1788 }
static struct ast_custom_function calendar_busy_function
static ast_cond_t refresh_condition
Definition: res_calendar.c:205
static struct ao2_container * calendars
Definition: res_calendar.c:201
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static pthread_t refresh_thread
Definition: res_calendar.c:203
static struct ast_custom_function calendar_query_result_function
Definition: sched.c:57
#define ast_cond_init(cond, attr)
Definition: lock.h:167
static int calendar_hash_fn(const void *obj, const int flags)
Definition: res_calendar.c:260
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:371
static struct ast_custom_function calendar_write_function
#define CALENDAR_BUCKETS
Definition: res_calendar.c:199
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define LOG_ERROR
Definition: logger.h:155
static struct ast_cli_entry calendar_cli[]
static ast_mutex_t refreshlock
Definition: res_calendar.c:204
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int calendar_cmp_fn(void *obj, void *arg, int flags)
Definition: res_calendar.c:266
static struct ast_custom_function calendar_event_function
static enum ast_device_state calendarstate(const char *data)
Definition: res_calendar.c:359
struct sched_context * sched_context_create(void)
New schedule context.
Definition: sched.c:246
static int load_config(int reload)
Definition: res_calendar.c:973
static ast_mutex_t reloadlock
Definition: res_calendar.c:206
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
#define ast_mutex_init(pmutex)
Definition: lock.h:152
static void * do_refresh(void *data)
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
static struct ast_custom_function calendar_query_function
static int load_tech_calendars ( struct ast_calendar_tech tech)
static

Definition at line 454 of file res_calendar.c.

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

Referenced by ast_calendar_register(), and reload().

455 {
456  struct ast_calendar *cal;
457  const char *cat = NULL;
458  const char *val;
459 
460  if (!calendar_config) {
461  ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type);
462  return -1;
463  }
464 
466  while ((cat = ast_category_browse(calendar_config, cat))) {
467  if (!strcasecmp(cat, "general")) {
468  continue;
469  }
470 
471  if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) {
472  continue;
473  }
474 
475  /* A serious error occurred loading calendars from this tech and it should be disabled */
476  if (!(cal = build_calendar(calendar_config, cat, tech))) {
479  return -1;
480  }
481 
482  cal = unref_calendar(cal);
483  }
484 
486 
487  return 0;
488 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
static struct ast_calendar * build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech)
Definition: res_calendar.c:378
#define ast_rwlock_unlock(a)
Definition: lock.h:200
const char * type
Definition: calendar.h:70
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
Definition: res_calendar.c:254
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_rwlock_wrlock(a)
Definition: lock.h:202
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
Definition: res_calendar.c:523
static struct ast_config * calendar_config
Definition: res_calendar.c:234
Asterisk calendar structure.
Definition: calendar.h:117
static ast_rwlock_t config_lock
Definition: res_calendar.c:235
static int match_caltech_cb ( void *  user_data,
void *  arg,
int  flags 
)
static

Definition at line 511 of file res_calendar.c.

References CMP_MATCH, and ast_calendar::tech.

Referenced by ast_calendar_unregister().

512 {
513  struct ast_calendar *cal = user_data;
514  struct ast_calendar_tech *tech = arg;
515 
516  if (cal->tech == tech) {
517  return CMP_MATCH;
518  }
519 
520  return 0;
521 }
struct ast_calendar_tech * tech
Definition: calendar.h:118
Individual calendaring technology data.
Definition: calendar.h:69
Asterisk calendar structure.
Definition: calendar.h:117
static int merge_events_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 924 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().

925 {
926  struct ast_calendar_event *old_event = obj, *new_event;
927  struct ao2_container *new_events = arg;
928 
929  /* If we don't find the old_event in new_events, then we can safely delete the old_event */
930  if (!(new_event = find_event(new_events, old_event->uid))) {
931  old_event = destroy_event(old_event);
932  return CMP_MATCH;
933  }
934 
935  /* We have events to merge. If any data that will affect a scheduler event has changed,
936  * then we need to replace the scheduler event */
937  schedule_calendar_event(old_event->owner, old_event, new_event);
938 
939  /* Since we don't want to mess with cancelling sched events and adding new ones, just
940  * copy the internals of the new_event to the old_event */
941  copy_event_data(old_event, new_event);
942 
943  /* Now we can go ahead and unlink the new_event from new_events and unref it so that only completely
944  * new events remain in the container */
945  ao2_unlink(new_events, new_event);
946  new_event = ast_calendar_unref_event(new_event);
947 
948  return 0;
949 }
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:862
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
Definition: res_calendar.c:562
static void copy_event_data(struct ast_calendar_event *dst, struct ast_calendar_event *src)
Definition: res_calendar.c:834
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:292
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:300
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
static int null_chan_write ( struct ast_channel chan,
struct ast_frame frame 
)
static

Definition at line 665 of file res_calendar.c.

666 {
667  return 0;
668 }
static int reload ( void  )
static

Definition at line 1662 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, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and ast_calendar_tech::type.

1663 {
1664  struct ast_calendar_tech *iter;
1665 
1667 
1668  /* Mark existing calendars for deletion */
1670  load_config(1);
1671 
1672  AST_LIST_LOCK(&techs);
1673  AST_LIST_TRAVERSE(&techs, iter, list) {
1674  if (load_tech_calendars(iter)) {
1675  ast_log(LOG_WARNING, "Failed to reload %s calendars, module disabled\n", iter->type);
1676  }
1677  }
1679 
1680  /* Delete calendars that no longer show up in the config */
1682 
1684 
1685  return 0;
1686 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ao2_container * calendars
Definition: res_calendar.c:201
struct ast_calendar_tech::@145 list
static int load_tech_calendars(struct ast_calendar_tech *tech)
Definition: res_calendar.c:454
#define LOG_WARNING
Definition: logger.h:144
#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:910
#define ast_mutex_lock(a)
Definition: lock.h:155
const char * type
Definition: calendar.h:70
static int cb_pending_deletion(void *user_data, void *arg, int flags)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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)
Definition: res_calendar.c:973
Individual calendaring technology data.
Definition: calendar.h:69
static ast_mutex_t reloadlock
Definition: res_calendar.c:206
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int cb_rm_pending_deletion(void *user_data, void *arg, int flags)
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 862 of file res_calendar.c.

References ast_calendar_event::alarm, ao2_lock, ao2_unlock, ast_cond_signal, ast_debug, ast_mutex_lock, ast_mutex_unlock, AST_SCHED_REPLACE, ast_tvnow(), ast_calendar::autoreminder, ast_calendar_event::bs_end_sched, ast_calendar_event::bs_start_sched, calendar_devstate_change(), calendar_event_notify(), ast_calendar_event::end, evententry::event, ast_calendar_event::notify_sched, and ast_calendar_event::start.

Referenced by add_new_event_cb(), and merge_events_cb().

863 {
864  struct timeval now = ast_tvnow();
865  struct ast_calendar_event *event;
866  time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end;
867  int changed = 0;
868 
869  event = cmp_event ? cmp_event : old_event;
870 
871  ao2_lock(event);
872  if (!cmp_event || old_event->alarm != event->alarm) {
873  changed = 1;
874  if (cal->autoreminder) {
875  alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000;
876  } else if (event->alarm) {
877  alarm_notify_sched = (event->alarm - now.tv_sec) * 1000;
878  }
879 
880  /* For now, send the notification if we missed it, but the meeting hasn't happened yet */
881  if (event->start >= now.tv_sec) {
882  if (alarm_notify_sched <= 0) {
883  alarm_notify_sched = 1;
884  }
886  AST_SCHED_REPLACE(old_event->notify_sched, sched, alarm_notify_sched, calendar_event_notify, old_event);
888  ast_debug(3, "Calendar alarm event notification scheduled to happen in %ld ms\n", (long) alarm_notify_sched);
889  }
890  }
891 
892  if (!cmp_event || old_event->start != event->start) {
893  changed = 1;
894  devstate_sched_start = (event->start - now.tv_sec) * 1000;
895 
896  if (devstate_sched_start < 1) {
897  devstate_sched_start = 1;
898  }
899 
901  AST_SCHED_REPLACE(old_event->bs_start_sched, sched, devstate_sched_start, calendar_devstate_change, old_event);
903  ast_debug(3, "Calendar bs_start event notification scheduled to happen in %ld ms\n", (long) devstate_sched_start);
904  }
905 
906  if (!cmp_event || old_event->end != event->end) {
907  changed = 1;
908  devstate_sched_end = (event->end - now.tv_sec) * 1000;
910  AST_SCHED_REPLACE(old_event->bs_end_sched, sched, devstate_sched_end, calendar_devstate_change, old_event);
912  ast_debug(3, "Calendar bs_end event notification scheduled to happen in %ld ms\n", (long) devstate_sched_end);
913  }
914 
915  if (changed) {
917  }
918 
919  ao2_unlock(event);
920 
921  return 0;
922 }
static int calendar_devstate_change(const void *data)
Definition: res_calendar.c:800
static ast_cond_t refresh_condition
Definition: res_calendar.c:205
static int calendar_event_notify(const void *data)
Definition: res_calendar.c:776
#define AST_SCHED_REPLACE(id, sched, when, callback, data)
Definition: sched.h:113
Definition: sched.c:57
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_cond_signal(cond)
Definition: lock.h:169
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_lock(a)
Definition: astobj2.h:488
static ast_mutex_t refreshlock
Definition: res_calendar.c:204
int autoreminder
Definition: calendar.h:128
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int unload_module ( void  )
static

Definition at line 1719 of file res_calendar.c.

References ao2_callback, 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_unload_resource(), calendar_busy_function, calendar_cli, calendar_config, calendar_event_function, calendar_query_function, calendar_query_result_function, calendar_write_function, evententry::list, ast_calendar_tech::module, OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

1720 {
1721  struct ast_calendar_tech *tech;
1722 
1723  ast_devstate_prov_del("calendar");
1730 
1731  /* Remove all calendars */
1733 
1735  module_unloading = 1;
1738  pthread_join(refresh_thread, NULL);
1739 
1740  AST_LIST_LOCK(&techs);
1742  ast_unload_resource(tech->module, 0);
1743  }
1746 
1748  calendar_config = NULL;
1749 
1750  return 0;
1751 }
static struct ast_custom_function calendar_busy_function
static ast_cond_t refresh_condition
Definition: res_calendar.c:205
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ao2_container * calendars
Definition: res_calendar.c:201
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_calendar_tech::@145 list
static pthread_t refresh_thread
Definition: res_calendar.c:203
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
#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:910
static struct ast_custom_function calendar_query_result_function
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:389
const char * module
Definition: calendar.h:72
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct ast_custom_function calendar_write_function
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_cond_signal(cond)
Definition: lock.h:169
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static struct ast_cli_entry calendar_cli[]
static ast_mutex_t refreshlock
Definition: res_calendar.c:204
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:551
static struct ast_custom_function calendar_event_function
static struct ast_config * calendar_config
Definition: res_calendar.c:234
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
static struct ast_custom_function calendar_query_function
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int module_unloading
Definition: res_calendar.c:207
static struct ast_calendar* unref_calendar ( struct ast_calendar cal)
static

Definition at line 254 of file res_calendar.c.

References ao2_ref.

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

255 {
256  ao2_ref(cal, -1);
257  return NULL;
258 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472

Variable Documentation

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

Definition at line 1794 of file res_calendar.c.

Definition at line 1794 of file res_calendar.c.

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

Referenced by load_module(), and unload_module().

struct ast_cli_entry calendar_cli[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_show_calendar, "Display information about a calendar"),
AST_CLI_DEFINE(handle_show_calendars, "Show registered calendars"),
AST_CLI_DEFINE(handle_dump_sched, "Dump calendar sched context"),
}
static char * handle_show_calendars(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command to list available calendars.
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_show_calendar(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_dump_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 1577 of file res_calendar.c.

Referenced by load_module(), and unload_module().

struct ast_config* calendar_config
static
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 1641 of file res_calendar.c.

Referenced by load_module(), and unload_module().

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

Definition at line 1207 of file res_calendar.c.

Referenced by load_module(), and unload_module().

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

Definition at line 1318 of file res_calendar.c.

Referenced by load_module(), and unload_module().

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

Definition at line 1425 of file res_calendar.c.

Referenced by load_module(), and unload_module().

struct ao2_container* calendars
static

Definition at line 201 of file res_calendar.c.

ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 }
static

Definition at line 235 of file res_calendar.c.

Referenced by ast_calendar_config_release(), load_config(), and load_tech_calendars().

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

Definition at line 214 of file res_calendar.c.

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

int module_unloading
static

Definition at line 207 of file res_calendar.c.

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:665

Definition at line 670 of file res_calendar.c.

Referenced by do_notify().

ast_cond_t refresh_condition
static

Definition at line 205 of file res_calendar.c.

pthread_t refresh_thread = AST_PTHREADT_NULL
static

Definition at line 203 of file res_calendar.c.

ast_mutex_t reloadlock
static

Definition at line 206 of file res_calendar.c.

struct sched_context* sched
static

Definition at line 202 of file res_calendar.c.

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