34 #include "asterisk/_private.h"
199 #define CALENDAR_BUCKETS 19
215 .
type =
"EventNotification",
221 .
type =
"CalendarEventList",
241 if (!calendar_config) {
315 pthread_join(cal->
thread, NULL);
382 int new_calendar = 0;
414 if (!strcasecmp(v->
name,
"autoreminder")) {
416 }
else if (!strcasecmp(v->
name,
"channel")) {
418 }
else if (!strcasecmp(v->
name,
"context")) {
420 }
else if (!strcasecmp(v->
name,
"extension")) {
422 }
else if (!strcasecmp(v->
name,
"waittime")) {
423 int i = atoi(v->
value);
427 }
else if (!strcasecmp(v->
name,
"app")) {
429 }
else if (!strcasecmp(v->
name,
"appdata")) {
431 }
else if (!strcasecmp(v->
name,
"refresh")) {
433 }
else if (!strcasecmp(v->
name,
"timeframe")) {
457 const char *cat = NULL;
467 if (!strcasecmp(cat,
"general")) {
496 if(!strcasecmp(tech->
type, iter->
type)) {
516 if (cal->
tech == tech) {
537 ast_verb(2,
"Unregistered calendar type '%s'\n", tech->
type);
553 if (attendee->
data) {
565 ast_debug(3,
"Notification running, can't delete sched entry\n");
568 ast_debug(3,
"Devicestate update (start) running, can't delete sched entry\n");
571 ast_debug(3,
"Devicestate update (end) running, can't delete sched entry\n");
598 ast_debug(3,
"Clearing all events for calendar %s\n", cal->
name);
616 event->notify_sched = -1;
617 event->bs_start_sched = -1;
618 event->bs_end_sched = -1;
654 unsigned long val[4];
657 for (x = 0; x < 4; x++) {
660 snprintf(buf, size,
"%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
672 .description =
"Null channel (should not see this)",
680 struct ast_str *apptext = NULL;
689 if ((dest = strchr(tech,
'/'))) {
710 if (!(chan =
ast_channel_alloc(1,
AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0,
"Calendar/%s-%s",
event->
owner->
name, buf))) {
720 ast_log(
LOG_ERROR,
"Could not allocate datastore, notification not being sent!\n");
788 event->notify_sched = -1;
813 is_end_event =
event->end <= now.tv_sec;
816 event->bs_end_sched = -1;
818 event->bs_start_sched = -1;
866 time_t alarm_notify_sched = 0, devstate_sched_start, devstate_sched_end;
869 event = cmp_event ? cmp_event : old_event;
872 if (!cmp_event || old_event->
alarm != event->
alarm) {
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;
881 if (event->
start >= now.tv_sec) {
882 if (alarm_notify_sched <= 0) {
883 alarm_notify_sched = 1;
888 ast_debug(3,
"Calendar alarm event notification scheduled to happen in %ld ms\n", (
long) alarm_notify_sched);
892 if (!cmp_event || old_event->
start != event->
start) {
894 devstate_sched_start = (
event->start - now.tv_sec) * 1000;
896 if (devstate_sched_start < 1) {
897 devstate_sched_start = 1;
903 ast_debug(3,
"Calendar bs_start event notification scheduled to happen in %ld ms\n", (
long) devstate_sched_start);
906 if (!cmp_event || old_event->
end != event->
end) {
908 devstate_sched_end = (
event->end - now.tv_sec) * 1000;
912 ast_debug(3,
"Calendar bs_end event notification scheduled to happen in %ld ms\n", (
long) devstate_sched_end);
978 if (!(tmpcfg =
ast_config_load2(
"calendar.conf",
"calendar", config_flags)) ||
1005 ast_log(
LOG_WARNING,
"CALENDAR_BUSY requires an argument: CALENDAR_BUSY(<calendar_name>)\n");
1023 .
name =
"CALENDAR_BUSY",
1030 int event_startdiff = abs(start - event->
start);
1031 int event_enddiff = abs(end - event->
end);
1034 if (!(entry =
ast_calloc(1,
sizeof(*entry)))) {
1044 int startdiff = abs(iter->
event->
start - start);
1046 ast_debug(10,
"Comparing %s with startdiff %d to %s with startdiff %d\n", event->
summary, event_startdiff, iter->
event->
summary, startdiff);
1048 if (startdiff > event_startdiff) {
1052 if (startdiff == event_startdiff) {
1053 int enddiff = abs(iter->
event->
end - end);
1055 if (enddiff > event_enddiff) {
1059 if (event_startdiff == enddiff) {
1127 time_t start = INT_MIN, end = INT_MAX;
1159 start = atoi(
args.start);
1163 end = atoi(
args.end);
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);
1208 .
name =
"CALENDAR_QUERY",
1263 if (!(events = datastore->
data)) {
1269 row = atoi(
args.row);
1276 if (!strcasecmp(
args.field,
"getnum")) {
1277 snprintf(buf, len,
"%zu", listlen);
1285 if (!strcasecmp(
args.field,
"summary")) {
1287 }
else if (!strcasecmp(
args.field,
"description")) {
1289 }
else if (!strcasecmp(
args.field,
"organizer")) {
1291 }
else if (!strcasecmp(
args.field,
"location")) {
1293 }
else if (!strcasecmp(
args.field,
"categories")) {
1295 }
else if (!strcasecmp(
args.field,
"priority")) {
1297 }
else if (!strcasecmp(
args.field,
"calendar")) {
1299 }
else if (!strcasecmp(
args.field,
"uid")) {
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")) {
1307 }
else if (!strcasecmp(
args.field,
"attendees")) {
1319 .
name =
"CALENDAR_QUERY_RESULT",
1326 char *val_dup = NULL;
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);
1373 for (i = 1, j = 0; i < fields.argc; i++, j++) {
1374 if (!strcasecmp(fields.field[i],
"summary")) {
1376 }
else if (!strcasecmp(fields.field[i],
"description")) {
1378 }
else if (!strcasecmp(fields.field[i],
"organizer")) {
1380 }
else if (!strcasecmp(fields.field[i],
"location")) {
1382 }
else if (!strcasecmp(fields.field[i],
"categories")) {
1384 }
else if (!strcasecmp(fields.field[i],
"priority")) {
1385 event->priority = atoi(
values.value[j]);
1386 }
else if (!strcasecmp(fields.field[i],
"uid")) {
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]);
1400 event->start = tv.tv_sec;
1404 event->end = tv.tv_sec;
1426 .
name =
"CALENDAR_WRITE",
1433 #define FORMAT "%-20.20s %-10.10s %-6.6s\n"
1439 e->
command =
"calendar show calendars";
1441 "Usage: calendar show calendars\n"
1442 " Lists all registered calendars.\n";
1464 struct timeval tv = {
1480 #define FORMAT "%-17.17s : %-20.20s\n"
1481 #define FORMAT2 "%-12.12s: %-40.60s\n"
1490 e->
command =
"calendar show calendar";
1492 "Usage: calendar show calendar <calendar name>\n"
1493 " Displays information about a calendar\n";
1502 if (!strncasecmp(a->
word, cal->
name, strlen(a->
word)) && ++which > a->
n) {
1562 e->
command =
"calendar dump sched";
1564 "Usage: calendar dump sched\n"
1565 " Dump the calendar sched context";
1606 if (!(event = datastore->
data)) {
1611 if (!strcasecmp(data,
"summary")) {
1613 }
else if (!strcasecmp(data,
"description")) {
1615 }
else if (!strcasecmp(data,
"organizer")) {
1617 }
else if (!strcasecmp(data,
"location")) {
1619 }
else if (!strcasecmp(data,
"categories")) {
1621 }
else if (!strcasecmp(data,
"priority")) {
1622 snprintf(buf, len,
"%d", event->
priority);
1623 }
else if (!strcasecmp(data,
"calendar")) {
1625 }
else if (!strcasecmp(data,
"uid")) {
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")) {
1633 }
else if (!strcasecmp(data,
"attendees")) {
1642 .
name =
"CALENDAR_EVENT",
1692 struct timespec ts = {0,};
1697 while (!module_unloading) {
1702 ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
1709 if (module_unloading) {
1735 module_unloading = 1;
1738 pthread_join(refresh_thread, NULL);
1775 ast_log(
LOG_ERROR,
"Unable to start refresh thread--notifications disabled!\n");
static int calendar_devstate_change(const void *data)
static void * do_notify(void *data)
static void calendar_join_attendees(struct ast_calendar_event *event, char *buf, size_t len)
static char * handle_show_calendars(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command to list available calendars.
static char * generate_random_string(char *buf, size_t size)
Generate 32 byte random string (stolen from chan_sip.c)
enum sip_cc_notify_state state
#define ast_rwlock_rdlock(a)
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
static struct ast_custom_function calendar_busy_function
#define AST_CLI_DEFINE(fn, txt,...)
ast_device_state
Device States.
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...
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
static ast_cond_t refresh_condition
#define AST_LIST_LOCK(head)
Locks a list.
int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
Enables an option globally.
int ast_calendar_register(struct ast_calendar_tech *tech)
Register a new calendar technology.
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_link(arg1, arg2)
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
static struct ao2_container * calendars
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
#define AST_RWLOCK_DEFINE_STATIC(rwlock)
static int calendar_event_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static char * epoch_to_string(char *buf, size_t buflen, time_t epoch)
static int load_module(void)
static int calendar_event_notify(const void *data)
Main dialing structure. Contains global options, channels being dialed, and more! ...
static void eventlist_destroy(void *data)
static int load_tech_calendars(struct ast_calendar_tech *tech)
static pthread_t refresh_thread
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout)
Set the maximum time (globally) allowed for trying to ring phones.
static int clear_events_cb(void *user_data, void *arg, int flags)
static struct ast_datastore_info eventlist_datastore_info
void *(* unref_calendar)(void *obj)
static void * eventlist_duplicate(void *data)
char context[AST_MAX_CONTEXT]
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
#define ao2_iterator_next(arg1)
void ast_sched_dump(struct sched_context *con)
Dumps the scheduler contents Debugging: Dump the contents of the scheduler to stderr.
descriptor for a cli entry.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define ao2_callback(c, flags, cb_fn, arg)
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
Append a channel.
static int calendar_write_exec(struct ast_channel *chan, const char *cmd, char *data, const char *value)
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
static struct ast_custom_function calendar_query_result_function
static struct ast_calendar * find_calendar(const char *name)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Structure for variables, used for configurations and for channel variables.
#define AST_SCHED_REPLACE(id, sched, when, callback, data)
static int event_hash_fn(const void *obj, const int flags)
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Structure for a data store type.
Configuration File Parser.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cond_init(cond, attr)
const ast_string_field notify_app
static int calendar_hash_fn(const void *obj, const int flags)
struct ast_module_user * user
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
const ast_string_field uid
enum ast_calendar_busy_state busy_state
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
static struct ast_calendar * build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech)
#define ast_mutex_lock(a)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Structure for a data store object.
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.
static int null_chan_write(struct ast_channel *chan, struct ast_frame *frame)
const ast_string_field notify_context
static void eventlist_destructor(void *obj)
void ast_cli(int fd, const char *fmt,...)
#define ast_rwlock_unlock(a)
static void * event_notification_duplicate(void *data)
#define ast_module_user_remove(user)
static struct ast_custom_function calendar_write_function
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define ast_cond_signal(cond)
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
const ast_string_field description
#define ast_verb(level,...)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
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,...)
static int calendar_busy_callback(void *obj, void *arg, int flags)
const ast_string_field organizer
static int schedule_calendar_event(struct ast_calendar *cal, struct ast_calendar_event *old_event, struct ast_calendar_event *cmp_event)
pthread_cond_t ast_cond_t
struct ast_config * ast_calendar_config_acquire(void)
Grab and lock pointer to the calendar config (read only)
#define ast_pthread_create_background(a, b, c, d)
void ast_calendar_clear_events(struct ast_calendar *cal)
Remove all events from calendar.
static struct ast_channel_tech null_tech
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static struct ast_calendar_event * destroy_event(struct ast_calendar_event *event)
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.
#define ast_debug(level,...)
Log a DEBUG message.
const ast_string_field location
ast_dial_result
List of return codes for dial run API calls.
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.
General Asterisk PBX channel definitions.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define AST_PTHREADT_NULL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Data structure associated with a custom dialplan function.
struct ao2_container * ast_calendar_event_container_alloc(void)
Allocate an astobj2 container for ast_calendar_event objects.
Scheduler Routines (derived from cheops)
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
const ast_string_field notify_appdata
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define ao2_ref(o, delta)
long int ast_random(void)
A general API for managing calendar events with Asterisk.
A set of macros to manage forward-linked lists.
struct evententry::@323 list
static char * handle_show_calendar(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void calendar_destructor(void *obj)
static void copy_event_data(struct ast_calendar_event *dst, struct ast_calendar_event *src)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct ast_calendar_tech * tech
#define ast_module_user_add(chan)
const ast_string_field name
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Core PBX routines and definitions.
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
struct ast_calendar_event * event
struct ao2_container * events
static struct sched_context * sched
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
static void calendar_event_destructor(void *obj)
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int calendar_busy_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
A dialplan function that can be used to determine the busy status of a calendar.
static int calendar_query_result_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
struct ast_calendar_event * ast_calendar_event_alloc(struct ast_calendar *cal)
Allocate an astobj2 ast_calendar_event object.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
static struct ast_cli_entry calendar_cli[]
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static int add_event_to_list(struct eventlist *events, struct ast_calendar_event *event, time_t start, time_t end)
static int cb_pending_deletion(void *user_data, void *arg, int flags)
static struct ast_calendar * unref_calendar(struct ast_calendar *cal)
static ast_mutex_t refreshlock
static int calendar_is_busy(struct ast_calendar *cal)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int merge_events_cb(void *obj, void *arg, int flags)
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
const ast_string_field name
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...
int(* write_event)(struct ast_calendar_event *event)
#define ao2_alloc(data_size, destructor_fn)
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define ao2_find(arg1, arg2, arg3)
#define ast_channel_unlock(chan)
static void event_notification_destroy(void *data)
#define ast_pthread_create(a, b, c, d)
struct ast_dial * ast_dial_create(void)
New dialing structure.
struct ast_calendar * owner
static struct ast_calendar_event * find_event(struct ao2_container *events, const char *uid)
void *(* load_calendar)(void *data)
static int calendar_cmp_fn(void *obj, void *arg, int flags)
const ast_string_field notify_extension
#define DATASTORE_INHERIT_FOREVER
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...
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
static int add_new_event_cb(void *obj, void *arg, int flags)
int(* is_busy)(struct ast_calendar *calendar)
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Structure used to handle boolean flags.
const ast_string_field categories
static struct ast_custom_function calendar_event_function
struct ast_calendar_event::attendees attendees
int ast_sched_runq(struct sched_context *con)
Runs the queue.
static int event_cmp_fn(void *obj, void *arg, int flags)
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
#define ast_rwlock_wrlock(a)
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
static enum ast_device_state calendarstate(const char *data)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_FORMAT_SLINEAR
struct sched_context * sched_context_create(void)
New schedule context.
static int load_config(int reload)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
static struct ast_config * calendar_config
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static int match_caltech_cb(void *user_data, void *arg, int flags)
Individual calendaring technology data.
static ast_mutex_t reloadlock
#define ao2_container_alloc(arg1, arg2, arg3)
static int unload_module(void)
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
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...
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Data structure associated with a single frame of data.
static char * handle_dump_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_datastore_info event_notification_datastore
#define AST_APP_ARG(name)
Define an application argument.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
struct ast_variable * next
static struct adsi_event events[]
#define ast_mutex_init(pmutex)
Asterisk calendar structure.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define CONFIG_STATUS_FILEINVALID
void ast_calendar_config_release(void)
Release the calendar config.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
static ast_rwlock_t config_lock
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
const ast_string_field summary
struct ast_channel_tech * tech
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
#define ao2_unlink(arg1, arg2)
#define ast_cond_timedwait(cond, mutex, time)
static void * do_refresh(void *data)
#define ast_custom_function_register(acf)
Register a custom function.
static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
char exten[AST_MAX_EXTENSION]
Structure for mutex and tracking information.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static struct ast_custom_function calendar_query_function
const ast_string_field notify_channel
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
static int cb_rm_pending_deletion(void *user_data, void *arg, int flags)
static int module_unloading
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.