Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Functions | Variables
res_calendar_icalendar.c File Reference

Resource for handling iCalendar calendars. More...

#include "asterisk.h"
#include <libical/ical.h>
#include <ne_session.h>
#include <ne_uri.h>
#include <ne_request.h>
#include <ne_auth.h>
#include <ne_redirect.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/astobj2.h"
Include dependency graph for res_calendar_icalendar.c:

Go to the source code of this file.

Data Structures

struct  icalendar_pvt
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int auth_credentials (void *userdata, const char *realm, int attempts, char *username, char *secret)
 
static icalcomponent * fetch_icalendar (struct icalendar_pvt *pvt)
 
static int fetch_response_reader (void *data, const char *block, size_t len)
 
static void * ical_load_calendar (void *data)
 
static void icalendar_add_event (icalcomponent *comp, struct icaltime_span *span, void *data)
 
static void icalendar_destructor (void *obj)
 
static void icalendar_update_events (struct icalendar_pvt *pvt)
 
static time_t icalfloat_to_timet (icaltimetype time)
 
static int load_module (void)
 
static int unload_module (void)
 
static void * unref_icalendar (void *obj)
 

Variables

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

Detailed Description

Resource for handling iCalendar calendars.

Definition in file res_calendar_icalendar.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 552 of file res_calendar_icalendar.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 552 of file res_calendar_icalendar.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 552 of file res_calendar_icalendar.c.

◆ auth_credentials()

static int auth_credentials ( void *  userdata,
const char *  realm,
int  attempts,
char *  username,
char *  secret 
)
static

Definition at line 113 of file res_calendar_icalendar.c.

114{
115 struct icalendar_pvt *pvt = userdata;
116
117 if (attempts > 1) {
118 ast_log(LOG_WARNING, "Invalid username or password for iCalendar '%s'\n", pvt->owner->name);
119 return -1;
120 }
121
122 ne_strnzcpy(username, pvt->user, NE_ABUFSIZ);
123 ne_strnzcpy(secret, pvt->secret, NE_ABUFSIZ);
124
125 return 0;
126}
#define ast_log
Definition: astobj2.c:42
#define LOG_WARNING
const ast_string_field name
Definition: calendar.h:129
struct ast_calendar * owner
const ast_string_field user
const ast_string_field secret

References ast_log, LOG_WARNING, ast_calendar::name, icalendar_pvt::owner, icalendar_pvt::secret, and icalendar_pvt::user.

Referenced by ical_load_calendar().

◆ fetch_icalendar()

static icalcomponent * fetch_icalendar ( struct icalendar_pvt pvt)
static

Definition at line 128 of file res_calendar_icalendar.c.

129{
130 int ret;
131 struct ast_str *response;
132 ne_request *req;
133 icalcomponent *comp = NULL;
134
135 if (!pvt) {
136 ast_log(LOG_ERROR, "There is no private!\n");
137 return NULL;
138 }
139
140 if (!(response = ast_str_create(512))) {
141 ast_log(LOG_ERROR, "Could not allocate memory for response.\n");
142 return NULL;
143 }
144
145 req = ne_request_create(pvt->session, "GET", pvt->uri.path);
146 ne_add_response_body_reader(req, ne_accept_2xx, fetch_response_reader, &response);
147
148 ret = ne_request_dispatch(req);
149 ne_request_destroy(req);
150 if (ret != NE_OK || !ast_str_strlen(response)) {
151 ast_log(LOG_WARNING, "Unable to retrieve iCalendar '%s' from '%s': %s\n", pvt->owner->name, pvt->url, ne_get_error(pvt->session));
152 ast_free(response);
153 return NULL;
154 }
155
156 if (!ast_strlen_zero(ast_str_buffer(response))) {
157 comp = icalparser_parse_string(ast_str_buffer(response));
158 if (!comp) {
159 ast_debug(3, "iCalendar response data: %s\n", ast_str_buffer(response));
160 ast_log(LOG_WARNING, "Failed to parse iCalendar data: %s\n", icalerror_perror());
161 }
162 }
163 ast_free(response);
164
165 return comp;
166}
#define ast_free(a)
Definition: astmm.h:180
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
static int fetch_response_reader(void *data, const char *block, size_t len)
#define NULL
Definition: resample.c:96
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
Support for dynamic strings.
Definition: strings.h:623
const ast_string_field url

References ast_debug, ast_free, ast_log, ast_str_buffer(), ast_str_create, ast_str_strlen(), ast_strlen_zero(), fetch_response_reader(), LOG_ERROR, LOG_WARNING, ast_calendar::name, NULL, icalendar_pvt::owner, icalendar_pvt::session, icalendar_pvt::uri, and icalendar_pvt::url.

Referenced by ical_load_calendar().

◆ fetch_response_reader()

static int fetch_response_reader ( void *  data,
const char *  block,
size_t  len 
)
static

Definition at line 97 of file res_calendar_icalendar.c.

98{
99 struct ast_str **response = data;
100 unsigned char *tmp;
101
102 if (!(tmp = ast_malloc(len + 1))) {
103 return -1;
104 }
105 memcpy(tmp, block, len);
106 tmp[len] = '\0';
107 ast_str_append(response, 0, "%s", tmp);
108 ast_free(tmp);
109
110 return 0;
111}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static int tmp()
Definition: bt_open.c:389
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139

References ast_free, ast_malloc, ast_str_append(), len(), and tmp().

Referenced by fetch_icalendar().

◆ ical_load_calendar()

static void * ical_load_calendar ( void *  data)
static

Definition at line 389 of file res_calendar_icalendar.c.

390{
391 struct icalendar_pvt *pvt;
392 const struct ast_config *cfg;
393 struct ast_variable *v;
394 struct ast_calendar *cal = void_data;
396
397 if (!(cal && (cfg = ast_calendar_config_acquire()))) {
398 ast_log(LOG_ERROR, "You must enable calendar support for res_icalendar to load\n");
399 return NULL;
400 }
401 if (ao2_trylock(cal)) {
402 if (cal->unloading) {
403 ast_log(LOG_WARNING, "Unloading module, load_calendar cancelled.\n");
404 } else {
405 ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n");
406 }
408 return NULL;
409 }
410
411 if (!(pvt = ao2_alloc(sizeof(*pvt), icalendar_destructor))) {
412 ast_log(LOG_ERROR, "Could not allocate icalendar_pvt structure for calendar: %s\n", cal->name);
414 return NULL;
415 }
416
417 pvt->owner = cal;
418
420 ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name);
421 pvt = unref_icalendar(pvt);
422 ao2_unlock(cal);
424 return NULL;
425 }
426
427 if (ast_string_field_init(pvt, 32)) {
428 ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name);
429 pvt = unref_icalendar(pvt);
430 ao2_unlock(cal);
432 return NULL;
433 }
434
435 for (v = ast_variable_browse(cfg, cal->name); v; v = v->next) {
436 if (!strcasecmp(v->name, "url")) {
438 } else if (!strcasecmp(v->name, "user")) {
440 } else if (!strcasecmp(v->name, "secret")) {
441 ast_string_field_set(pvt, secret, v->value);
442 }
443 }
444
446
447 if (ast_strlen_zero(pvt->url)) {
448 ast_log(LOG_WARNING, "No URL was specified for iCalendar '%s' - skipping.\n", cal->name);
449 pvt = unref_icalendar(pvt);
450 ao2_unlock(cal);
451 return NULL;
452 }
453
454 if (ne_uri_parse(pvt->url, &pvt->uri) || pvt->uri.host == NULL || pvt->uri.path == NULL) {
455 ast_log(LOG_WARNING, "Could not parse url '%s' for iCalendar '%s' - skipping.\n", pvt->url, cal->name);
456 pvt = unref_icalendar(pvt);
457 ao2_unlock(cal);
458 return NULL;
459 }
460
461 if (pvt->uri.scheme == NULL) {
462 pvt->uri.scheme = "http";
463 }
464
465 if (pvt->uri.port == 0) {
466 pvt->uri.port = ne_uri_defaultport(pvt->uri.scheme);
467 }
468
469 pvt->session = ne_session_create(pvt->uri.scheme, pvt->uri.host, pvt->uri.port);
470 ne_redirect_register(pvt->session);
471 ne_set_server_auth(pvt->session, auth_credentials, pvt);
472 ne_set_useragent(pvt->session, "Asterisk");
473 if (!strcasecmp(pvt->uri.scheme, "https")) {
474 ne_ssl_trust_default_ca(pvt->session);
475 }
476
477 cal->tech_pvt = pvt;
478
480
481 /* Load it the first time */
482 if (!(pvt->data = fetch_icalendar(pvt))) {
483 ast_log(LOG_WARNING, "Unable to parse iCalendar '%s'\n", cal->name);
484 }
485
487
488 ao2_unlock(cal);
489
490 /* The only writing from another thread will be if unload is true */
491 for(;;) {
492 struct timeval tv = ast_tvnow();
493 struct timespec ts = {0,};
494
495 ts.tv_sec = tv.tv_sec + (60 * pvt->owner->refresh);
496
498 while (!pvt->owner->unloading) {
499 if (ast_cond_timedwait(&pvt->owner->unload, &refreshlock, &ts) == ETIMEDOUT) {
500 break;
501 }
502 }
504
505 if (pvt->owner->unloading) {
506 ast_debug(10, "Skipping refresh since we got a shutdown signal\n");
507 return NULL;
508 }
509
510 ast_debug(10, "Refreshing after %d minute timeout\n", pvt->owner->refresh);
511
512 /* Free the old calendar data */
513 if (pvt->data) {
514 icalcomponent_free(pvt->data);
515 pvt->data = NULL;
516 }
517 if (!(pvt->data = fetch_icalendar(pvt))) {
518 ast_log(LOG_WARNING, "Unable to parse iCalendar '%s'\n", pvt->owner->name);
519 continue;
520 }
521
523 }
524
525 return NULL;
526}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_trylock(a)
Definition: astobj2.h:739
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
void ast_calendar_config_release(void)
Release the calendar config.
Definition: res_calendar.c:272
struct ao2_container * ast_calendar_event_container_alloc(void)
Allocate an astobj2 container for ast_calendar_event objects.
Definition: res_calendar.c:691
const struct ast_config * ast_calendar_config_acquire(void)
Grab and lock pointer to the calendar config (read only)
Definition: res_calendar.c:260
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
static ast_mutex_t refreshlock
Definition: res_calendar.c:227
static void icalendar_destructor(void *obj)
static icalcomponent * fetch_icalendar(struct icalendar_pvt *pvt)
static void icalendar_update_events(struct icalendar_pvt *pvt)
static void * unref_icalendar(void *obj)
static int auth_credentials(void *userdata, const char *realm, int attempts, char *username, char *secret)
static char url[512]
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Asterisk calendar structure.
Definition: calendar.h:119
void * tech_pvt
Definition: calendar.h:121
ast_cond_t unload
Definition: calendar.h:137
unsigned int unloading
Definition: calendar.h:138
Structure for mutex and tracking information.
Definition: lock.h:135
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
icalcomponent * data
struct ao2_container * events
structure to hold users read from users.conf
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ao2_alloc, ao2_trylock, ao2_unlock, ast_calendar_config_acquire(), ast_calendar_config_release(), ast_calendar_event_container_alloc(), ast_cond_timedwait, ast_debug, ast_log, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), ast_variable_browse(), auth_credentials(), icalendar_pvt::data, icalendar_pvt::events, fetch_icalendar(), icalendar_destructor(), icalendar_update_events(), LOG_ERROR, LOG_WARNING, ast_calendar::name, ast_variable::name, ast_variable::next, NULL, icalendar_pvt::owner, ast_calendar::refresh, refreshlock, icalendar_pvt::session, ast_calendar::tech_pvt, ast_calendar::unload, ast_calendar::unloading, unref_icalendar(), icalendar_pvt::uri, icalendar_pvt::url, url, and ast_variable::value.

◆ icalendar_add_event()

static void icalendar_add_event ( icalcomponent *  comp,
struct icaltime_span *  span,
void *  data 
)
static

Definition at line 194 of file res_calendar_icalendar.c.

195{
196 struct icalendar_pvt *pvt = data;
198 icaltimezone *utc = icaltimezone_get_utc_timezone();
199 icaltimetype start, end, tmp;
200 icalcomponent *valarm;
201 icalproperty *prop;
202 struct icaltriggertype trigger;
203
204 if (!(pvt && pvt->owner)) {
205 ast_log(LOG_ERROR, "Require a private structure with an owner\n");
206 return;
207 }
208
209 if (!(event = ast_calendar_event_alloc(pvt->owner))) {
210 ast_log(LOG_ERROR, "Could not allocate an event!\n");
211 return;
212 }
213
214 start = icalcomponent_get_dtstart(comp);
215 end = icalcomponent_get_dtend(comp);
216
217 event->start = icaltime_get_tzid(start) ? span->start : icalfloat_to_timet(start);
218 event->end = icaltime_get_tzid(end) ? span->end : icalfloat_to_timet(end);
219 event->busy_state = span->is_busy ? AST_CALENDAR_BS_BUSY : AST_CALENDAR_BS_FREE;
220
221 if ((prop = icalcomponent_get_first_property(comp, ICAL_SUMMARY_PROPERTY))) {
222 ast_string_field_set(event, summary, icalproperty_get_value_as_string(prop));
223 }
224
225 if ((prop = icalcomponent_get_first_property(comp, ICAL_DESCRIPTION_PROPERTY))) {
226 ast_string_field_set(event, description, icalproperty_get_value_as_string(prop));
227 }
228
229 if ((prop = icalcomponent_get_first_property(comp, ICAL_ORGANIZER_PROPERTY))) {
230 ast_string_field_set(event, organizer, icalproperty_get_value_as_string(prop));
231 }
232
233 if ((prop = icalcomponent_get_first_property(comp, ICAL_LOCATION_PROPERTY))) {
234 ast_string_field_set(event, location, icalproperty_get_value_as_string(prop));
235 }
236
237 if ((prop = icalcomponent_get_first_property(comp, ICAL_CATEGORIES_PROPERTY))) {
238 ast_string_field_set(event, categories, icalproperty_get_value_as_string(prop));
239 }
240
241 if ((prop = icalcomponent_get_first_property(comp, ICAL_PRIORITY_PROPERTY))) {
242 event->priority = icalvalue_get_integer(icalproperty_get_value(prop));
243 }
244
245 if ((prop = icalcomponent_get_first_property(comp, ICAL_UID_PROPERTY))) {
246 ast_string_field_set(event, uid, icalproperty_get_value_as_string(prop));
247 } else {
248 ast_log(LOG_WARNING, "No UID found, but one is required. Generating, but updates may not be accurate\n");
249 if (!ast_strlen_zero(event->summary)) {
250 ast_string_field_set(event, uid, event->summary);
251 } else {
252 char tmp[AST_TIME_T_LEN];
253 ast_time_t_to_string(event->start, tmp, sizeof(tmp));
255 }
256 }
257
258 /*
259 * If comp has an RRULE and/or RDATE property, we need to check whether
260 * another vevent component supercedes this span. Such a component would
261 * have two characteristics:
262 * - its UID is the same as comp
263 * - its RECURRENCE-ID property is the same time as span->start
264 */
265 if (icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY)
266 || icalcomponent_get_first_property(comp, ICAL_RDATE_PROPERTY)) {
267 icalcompiter comp_iter;
268 icaltimetype span_start = icaltime_from_timet_with_zone(
269 event->start, icaltime_is_date(start), icaltime_get_timezone(start));
270
271 icaltime_set_timezone(&span_start, icaltime_get_timezone(start));
272 for (comp_iter = icalcomponent_begin_component(pvt->data, ICAL_VEVENT_COMPONENT);
273 icalcompiter_deref(&comp_iter);
274 icalcompiter_next(&comp_iter)) {
275 icalcomponent *vevent = icalcompiter_deref(&comp_iter);
276 icalproperty *uid = icalcomponent_get_first_property(vevent, ICAL_UID_PROPERTY);
277
278 if (uid && !strcmp(icalproperty_get_value_as_string(uid), event->uid)) {
279 icaltimetype recurrence_id = icalcomponent_get_recurrenceid(vevent);
280
281 /* Set the same timezone that we want to compare against */
282 icaltime_set_timezone(&recurrence_id, icaltime_get_timezone(start));
283
284 if (!icaltime_compare(recurrence_id, span_start)
285 && icaltime_is_date(span_start) == icaltime_is_date(recurrence_id)) {
287 return;
288 }
289 }
290 }
291 }
292
293 /* Get the attendees */
294 for (prop = icalcomponent_get_first_property(comp, ICAL_ATTENDEE_PROPERTY);
295 prop; prop = icalcomponent_get_next_property(comp, ICAL_ATTENDEE_PROPERTY)) {
296 struct ast_calendar_attendee *attendee;
297 const char *data;
298
299 if (!(attendee = ast_calloc(1, sizeof(*attendee)))) {
301 return;
302 }
303 data = icalproperty_get_attendee(prop);
304 if (ast_strlen_zero(data)) {
305 ast_free(attendee);
306 continue;
307 }
308 attendee->data = ast_strdup(data);;
309 AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
310 }
311
312
313 /* Only set values for alarm based on VALARM. Can be overriden in main/calendar.c by autoreminder
314 * therefore, go ahead and add events even if their is no VALARM or it is malformed
315 * Currently we are only getting the first VALARM and are handling repitition in main/calendar.c from calendar.conf */
316 if (!(valarm = icalcomponent_get_first_component(comp, ICAL_VALARM_COMPONENT))) {
317 ao2_link(pvt->events, event);
319 return;
320 }
321
322 if (!(prop = icalcomponent_get_first_property(valarm, ICAL_TRIGGER_PROPERTY))) {
323 ast_log(LOG_WARNING, "VALARM has no TRIGGER, skipping!\n");
324 ao2_link(pvt->events, event);
326 return;
327 }
328
329 trigger = icalproperty_get_trigger(prop);
330
331 if (icaltriggertype_is_null_trigger(trigger)) {
332 ast_log(LOG_WARNING, "Bad TRIGGER for VALARM, skipping!\n");
333 ao2_link(pvt->events, event);
335 return;
336 }
337
338 if (!icaltime_is_null_time(trigger.time)) { /* This is an absolute time */
339 tmp = icaltime_convert_to_zone(trigger.time, utc);
340 event->alarm = icaltime_as_timet_with_zone(tmp, utc);
341 } else { /* Offset from either dtstart or dtend */
342 /* XXX Technically you can check RELATED to see if the event fires from the END of the event
343 * But, I'm not sure I've ever seen anyone implement it in calendaring software, so I'm ignoring for now */
344 tmp = icaltime_add(start, trigger.duration);
345 event->alarm = icaltime_as_timet_with_zone(tmp, icaltime_get_timezone(start));
346 }
347
348 ao2_link(pvt->events, event);
350
351 return;
352}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AST_CALENDAR_BS_FREE
Definition: calendar.h:84
@ AST_CALENDAR_BS_BUSY
Definition: calendar.h:86
struct ast_calendar_event * ast_calendar_event_alloc(struct ast_calendar *cal)
Allocate an astobj2 ast_calendar_event object.
Definition: res_calendar.c:669
struct ast_calendar_event * ast_calendar_unref_event(struct ast_calendar_event *event)
Unreference an ast_calendar_event.
Definition: res_calendar.c:323
char * end
Definition: eagi_proxy.c:73
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
static time_t icalfloat_to_timet(icaltimetype time)
struct ast_calendar_attendee * next
Definition: calendar.h:91
Calendar events.
Definition: calendar.h:95
Definition: astman.c:222
struct association categories[]
int ast_time_t_to_string(time_t time, char *buf, size_t length)
Converts to a string representation of a time_t as decimal seconds since the epoch....
Definition: time.c:152
#define AST_TIME_T_LEN
Definition: time.h:45

References ao2_link, AST_CALENDAR_BS_BUSY, AST_CALENDAR_BS_FREE, ast_calendar_event_alloc(), ast_calendar_unref_event(), ast_calloc, ast_free, AST_LIST_INSERT_TAIL, ast_log, ast_strdup, ast_string_field_set, ast_strlen_zero(), AST_TIME_T_LEN, ast_time_t_to_string(), categories, ast_calendar_attendee::data, icalendar_pvt::data, end, icalendar_pvt::events, icalfloat_to_timet(), LOG_ERROR, LOG_WARNING, ast_calendar_attendee::next, icalendar_pvt::owner, ast_calendar_event::start, and tmp().

Referenced by icalendar_update_events().

◆ icalendar_destructor()

static void icalendar_destructor ( void *  obj)
static

Definition at line 70 of file res_calendar_icalendar.c.

71{
72 struct icalendar_pvt *pvt = obj;
73
74 ast_debug(1, "Destroying pvt for iCalendar %s\n", pvt->owner->name);
75 if (pvt->session) {
76 ne_session_destroy(pvt->session);
77 }
78 if (pvt->data) {
79 icalcomponent_free(pvt->data);
80 }
81 ne_uri_free(&pvt->uri);
83
85
86 ao2_ref(pvt->events, -1);
87}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ao2_callback, ao2_ref, ast_debug, ast_string_field_free_memory, icalendar_pvt::data, icalendar_pvt::events, ast_calendar::name, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, icalendar_pvt::owner, icalendar_pvt::session, and icalendar_pvt::uri.

Referenced by ical_load_calendar().

◆ icalendar_update_events()

static void icalendar_update_events ( struct icalendar_pvt pvt)
static

Definition at line 354 of file res_calendar_icalendar.c.

355{
356 struct icaltimetype start_time, end_time;
357 icalcomponent *iter;
358
359 if (!pvt) {
360 ast_log(LOG_ERROR, "iCalendar is NULL\n");
361 return;
362 }
363
364 if (!pvt->owner) {
365 ast_log(LOG_ERROR, "iCalendar is an orphan!\n");
366 return;
367 }
368
369 if (!pvt->data) {
370 ast_log(LOG_ERROR, "The iCalendar has not been parsed!\n");
371 return;
372 }
373
374 start_time = icaltime_current_time_with_zone(icaltimezone_get_utc_timezone());
375 end_time = icaltime_current_time_with_zone(icaltimezone_get_utc_timezone());
376 end_time.second += pvt->owner->timeframe * 60;
377 end_time = icaltime_normalize(end_time);
378
379 for (iter = icalcomponent_get_first_component(pvt->data, ICAL_VEVENT_COMPONENT);
380 iter;
381 iter = icalcomponent_get_next_component(pvt->data, ICAL_VEVENT_COMPONENT))
382 {
383 icalcomponent_foreach_recurrence(iter, start_time, end_time, icalendar_add_event, pvt);
384 }
385
387}
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.
static void icalendar_add_event(icalcomponent *comp, struct icaltime_span *span, void *data)
int timeframe
Definition: calendar.h:135

References ast_calendar_merge_events(), ast_log, icalendar_pvt::data, icalendar_pvt::events, icalendar_add_event(), LOG_ERROR, icalendar_pvt::owner, and ast_calendar::timeframe.

Referenced by ical_load_calendar().

◆ icalfloat_to_timet()

static time_t icalfloat_to_timet ( icaltimetype  time)
static

Definition at line 168 of file res_calendar_icalendar.c.

169{
170 struct ast_tm tm = {0,};
171 struct timeval tv;
172
173 tm.tm_mday = time.day;
174 tm.tm_mon = time.month - 1;
175 tm.tm_year = time.year - 1900;
176 tm.tm_hour = time.hour;
177 tm.tm_min = time.minute;
178 tm.tm_sec = time.second;
179 tm.tm_isdst = -1;
180 tv = ast_mktime(&tm, NULL);
181
182 return tv.tv_sec;
183}
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2357
int tm_mday
Definition: localtime.h:39
int tm_sec
Definition: localtime.h:36
int tm_hour
Definition: localtime.h:38
int tm_isdst
Definition: localtime.h:44
int tm_min
Definition: localtime.h:37
int tm_year
Definition: localtime.h:41
int tm_mon
Definition: localtime.h:40

References ast_mktime(), NULL, ast_tm::tm_hour, ast_tm::tm_isdst, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.

Referenced by icalendar_add_event().

◆ load_module()

static int load_module ( void  )
static

Definition at line 528 of file res_calendar_icalendar.c.

529{
530 ne_sock_init();
532 ne_sock_exit();
534 }
535
537}
int ast_calendar_register(struct ast_calendar_tech *tech)
Register a new calendar technology.
Definition: res_calendar.c:551
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_calendar_tech ical_tech

References ast_calendar_register(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and ical_tech.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 539 of file res_calendar_icalendar.c.

540{
542 ne_sock_exit();
543 return 0;
544}
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
Definition: res_calendar.c:589

References ast_calendar_unregister(), and ical_tech.

◆ unref_icalendar()

static void * unref_icalendar ( void *  obj)
static

Definition at line 89 of file res_calendar_icalendar.c.

90{
91 struct icalendar_pvt *pvt = obj;
92
93 ao2_ref(pvt, -1);
94 return NULL;
95}

References ao2_ref, and NULL.

Referenced by ical_load_calendar().

Variable Documentation

◆ __mod_info

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

Definition at line 552 of file res_calendar_icalendar.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 552 of file res_calendar_icalendar.c.

◆ ical_tech

struct ast_calendar_tech ical_tech
static

Definition at line 49 of file res_calendar_icalendar.c.

Referenced by load_module(), and unload_module().