Wed Jan 8 2020 09:50:18

Asterisk developer's documentation


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/calendar.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  icalendar_pvt
 

Functions

static void __reg_module (void)
 
static void __unreg_module (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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEVSTATE_PLUGIN, }
 
static 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

static void __reg_module ( void  )
static

Definition at line 509 of file res_calendar_icalendar.c.

static void __unreg_module ( void  )
static

Definition at line 509 of file res_calendar_icalendar.c.

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

Definition at line 112 of file res_calendar_icalendar.c.

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

Referenced by ical_load_calendar().

113 {
114  struct icalendar_pvt *pvt = userdata;
115 
116  if (attempts > 1) {
117  ast_log(LOG_WARNING, "Invalid username or password for iCalendar '%s'\n", pvt->owner->name);
118  return -1;
119  }
120 
121  ne_strnzcpy(username, pvt->user, NE_ABUFSIZ);
122  ne_strnzcpy(secret, pvt->secret, NE_ABUFSIZ);
123 
124  return 0;
125 }
struct ast_calendar * owner
const ast_string_field user
const ast_string_field secret
#define LOG_WARNING
Definition: logger.h:144
const ast_string_field name
Definition: calendar.h:127
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 char secret[50]
Definition: chan_h323.c:148
static icalcomponent* fetch_icalendar ( struct icalendar_pvt pvt)
static

Definition at line 127 of file res_calendar_icalendar.c.

References 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, icalendar_pvt::owner, icalendar_pvt::session, icalendar_pvt::uri, and icalendar_pvt::url.

Referenced by ical_load_calendar().

128 {
129  int ret;
130  struct ast_str *response;
131  ne_request *req;
132  icalcomponent *comp = NULL;
133 
134  if (!pvt) {
135  ast_log(LOG_ERROR, "There is no private!\n");
136  return NULL;
137  }
138 
139  if (!(response = ast_str_create(512))) {
140  ast_log(LOG_ERROR, "Could not allocate memory for response.\n");
141  return NULL;
142  }
143 
144  req = ne_request_create(pvt->session, "GET", pvt->uri.path);
145  ne_add_response_body_reader(req, ne_accept_2xx, fetch_response_reader, &response);
146 
147  ret = ne_request_dispatch(req);
148  ne_request_destroy(req);
149  if (ret != NE_OK || !ast_str_strlen(response)) {
150  ast_log(LOG_WARNING, "Unable to retrieve iCalendar '%s' from '%s': %s\n", pvt->owner->name, pvt->url, ne_get_error(pvt->session));
151  ast_free(response);
152  return NULL;
153  }
154 
155  if (!ast_strlen_zero(ast_str_buffer(response))) {
156  comp = icalparser_parse_string(ast_str_buffer(response));
157  }
158  ast_free(response);
159 
160  return comp;
161 }
struct ast_calendar * owner
#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
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
static int fetch_response_reader(void *data, const char *block, size_t len)
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
#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
const ast_string_field url
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_free(a)
Definition: astmm.h:97
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static int fetch_response_reader ( void *  data,
const char *  block,
size_t  len 
)
static

Definition at line 96 of file res_calendar_icalendar.c.

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

Referenced by fetch_icalendar().

97 {
98  struct ast_str **response = data;
99  unsigned char *tmp;
100 
101  if (!(tmp = ast_malloc(len + 1))) {
102  return -1;
103  }
104  memcpy(tmp, block, len);
105  tmp[len] = '\0';
106  ast_str_append(response, 0, "%s", tmp);
107  ast_free(tmp);
108 
109  return 0;
110 }
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
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)
#define ast_free(a)
Definition: astmm.h:97
#define ast_malloc(a)
Definition: astmm.h:91
static void * ical_load_calendar ( void *  data)
static

Definition at line 349 of file res_calendar_icalendar.c.

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_variable::name, ast_calendar::name, ast_variable::next, icalendar_pvt::owner, ast_calendar::refresh, refreshlock, secret, 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.

350 {
351  struct icalendar_pvt *pvt;
352  const struct ast_config *cfg;
353  struct ast_variable *v;
354  struct ast_calendar *cal = void_data;
356 
357  if (!(cal && (cfg = ast_calendar_config_acquire()))) {
358  ast_log(LOG_ERROR, "You must enable calendar support for res_icalendar to load\n");
359  return NULL;
360  }
361  if (ao2_trylock(cal)) {
362  if (cal->unloading) {
363  ast_log(LOG_WARNING, "Unloading module, load_calendar cancelled.\n");
364  } else {
365  ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n");
366  }
368  return NULL;
369  }
370 
371  if (!(pvt = ao2_alloc(sizeof(*pvt), icalendar_destructor))) {
372  ast_log(LOG_ERROR, "Could not allocate icalendar_pvt structure for calendar: %s\n", cal->name);
374  return NULL;
375  }
376 
377  pvt->owner = cal;
378 
379  if (!(pvt->events = ast_calendar_event_container_alloc())) {
380  ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name);
381  pvt = unref_icalendar(pvt);
382  ao2_unlock(cal);
384  return NULL;
385  }
386 
387  if (ast_string_field_init(pvt, 32)) {
388  ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name);
389  pvt = unref_icalendar(pvt);
390  ao2_unlock(cal);
392  return NULL;
393  }
394 
395  for (v = ast_variable_browse(cfg, cal->name); v; v = v->next) {
396  if (!strcasecmp(v->name, "url")) {
397  ast_string_field_set(pvt, url, v->value);
398  } else if (!strcasecmp(v->name, "user")) {
399  ast_string_field_set(pvt, user, v->value);
400  } else if (!strcasecmp(v->name, "secret")) {
402  }
403  }
404 
406 
407  if (ast_strlen_zero(pvt->url)) {
408  ast_log(LOG_WARNING, "No URL was specified for iCalendar '%s' - skipping.\n", cal->name);
409  pvt = unref_icalendar(pvt);
410  ao2_unlock(cal);
411  return NULL;
412  }
413 
414  if (ne_uri_parse(pvt->url, &pvt->uri) || pvt->uri.host == NULL || pvt->uri.path == NULL) {
415  ast_log(LOG_WARNING, "Could not parse url '%s' for iCalendar '%s' - skipping.\n", pvt->url, cal->name);
416  pvt = unref_icalendar(pvt);
417  ao2_unlock(cal);
418  return NULL;
419  }
420 
421  if (pvt->uri.scheme == NULL) {
422  pvt->uri.scheme = "http";
423  }
424 
425  if (pvt->uri.port == 0) {
426  pvt->uri.port = ne_uri_defaultport(pvt->uri.scheme);
427  }
428 
429  pvt->session = ne_session_create(pvt->uri.scheme, pvt->uri.host, pvt->uri.port);
430  ne_redirect_register(pvt->session);
431  ne_set_server_auth(pvt->session, auth_credentials, pvt);
432  if (!strcasecmp(pvt->uri.scheme, "https")) {
433  ne_ssl_trust_default_ca(pvt->session);
434  }
435 
436  cal->tech_pvt = pvt;
437 
438  ast_mutex_init(&refreshlock);
439 
440  /* Load it the first time */
441  if (!(pvt->data = fetch_icalendar(pvt))) {
442  ast_log(LOG_WARNING, "Unable to parse iCalendar '%s'\n", cal->name);
443  }
444 
446 
447  ao2_unlock(cal);
448 
449  /* The only writing from another thread will be if unload is true */
450  for(;;) {
451  struct timeval tv = ast_tvnow();
452  struct timespec ts = {0,};
453 
454  ts.tv_sec = tv.tv_sec + (60 * pvt->owner->refresh);
455 
456  ast_mutex_lock(&refreshlock);
457  while (!pvt->owner->unloading) {
458  if (ast_cond_timedwait(&pvt->owner->unload, &refreshlock, &ts) == ETIMEDOUT) {
459  break;
460  }
461  }
462  ast_mutex_unlock(&refreshlock);
463 
464  if (pvt->owner->unloading) {
465  ast_debug(10, "Skipping refresh since we got a shutdown signal\n");
466  return NULL;
467  }
468 
469  ast_debug(10, "Refreshing after %d minute timeout\n", pvt->owner->refresh);
470 
471  /* Free the old calendar data */
472  if (pvt->data) {
473  icalcomponent_free(pvt->data);
474  pvt->data = NULL;
475  }
476  if (!(pvt->data = fetch_icalendar(pvt))) {
477  ast_log(LOG_WARNING, "Unable to parse iCalendar '%s'\n", pvt->owner->name);
478  continue;
479  }
480 
482  }
483 
484  return NULL;
485 }
static void * unref_icalendar(void *obj)
struct ast_calendar * owner
ast_cond_t unload
Definition: calendar.h:133
int unloading
Definition: calendar.h:134
static icalcomponent * fetch_icalendar(struct icalendar_pvt *pvt)
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ao2_container * events
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
static void icalendar_update_events(struct icalendar_pvt *pvt)
struct ast_config * ast_calendar_config_acquire(void)
Grab and lock pointer to the calendar config (read only)
Definition: res_calendar.c:237
void * tech_pvt
Definition: calendar.h:119
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int auth_credentials(void *userdata, const char *realm, int attempts, char *username, char *secret)
const char * value
Definition: config.h:79
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ao2_container * ast_calendar_event_container_alloc(void)
Allocate an astobj2 container for ast_calendar_event objects.
Definition: res_calendar.c:625
const char * name
Definition: config.h:77
const ast_string_field name
Definition: calendar.h:127
#define LOG_ERROR
Definition: logger.h:155
#define ao2_trylock(a)
Definition: astobj2.h:506
static ast_mutex_t refreshlock
Definition: res_calendar.c:204
const ast_string_field url
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 void icalendar_destructor(void *obj)
structure to hold users read from users.conf
static char secret[50]
Definition: chan_h323.c:148
icalcomponent * data
struct timeval tv
struct ast_variable * next
Definition: config.h:82
#define ast_mutex_init(pmutex)
Definition: lock.h:152
Asterisk calendar structure.
Definition: calendar.h:117
void ast_calendar_config_release(void)
Release the calendar config.
Definition: res_calendar.c:249
static char url[512]
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
Structure for mutex and tracking information.
Definition: lock.h:121
#define ast_mutex_unlock(a)
Definition: lock.h:156
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static void icalendar_add_event ( icalcomponent *  comp,
struct icaltime_span *  span,
void *  data 
)
static

Definition at line 189 of file res_calendar_icalendar.c.

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_calendar_event::attendees, icalendar_pvt::data, ast_calendar_attendee::data, ast_calendar_event::end, icalendar_pvt::events, icalfloat_to_timet(), LOG_ERROR, LOG_WARNING, ast_calendar_attendee::next, icalendar_pvt::owner, ast_calendar_event::start, and ast_calendar_event::summary.

Referenced by icalendar_update_events().

190 {
191  struct icalendar_pvt *pvt = data;
192  struct ast_calendar_event *event;
193  icaltimezone *utc = icaltimezone_get_utc_timezone();
194  icaltimetype start, end, tmp;
195  icalcomponent *valarm;
196  icalproperty *prop;
197  struct icaltriggertype trigger;
198 
199  if (!(pvt && pvt->owner)) {
200  ast_log(LOG_ERROR, "Require a private structure with an ownenr\n");
201  return;
202  }
203 
204  if (!(event = ast_calendar_event_alloc(pvt->owner))) {
205  ast_log(LOG_ERROR, "Could not allocate an event!\n");
206  return;
207  }
208 
209  start = icalcomponent_get_dtstart(comp);
210  end = icalcomponent_get_dtend(comp);
211 
212  event->start = icaltime_get_tzid(start) ? span->start : icalfloat_to_timet(start);
213  event->end = icaltime_get_tzid(end) ? span->end : icalfloat_to_timet(end);
214  event->busy_state = span->is_busy ? AST_CALENDAR_BS_BUSY : AST_CALENDAR_BS_FREE;
215 
216  if ((prop = icalcomponent_get_first_property(comp, ICAL_SUMMARY_PROPERTY))) {
217  ast_string_field_set(event, summary, icalproperty_get_value_as_string(prop));
218  }
219 
220  if ((prop = icalcomponent_get_first_property(comp, ICAL_DESCRIPTION_PROPERTY))) {
221  ast_string_field_set(event, description, icalproperty_get_value_as_string(prop));
222  }
223 
224  if ((prop = icalcomponent_get_first_property(comp, ICAL_ORGANIZER_PROPERTY))) {
225  ast_string_field_set(event, organizer, icalproperty_get_value_as_string(prop));
226  }
227 
228  if ((prop = icalcomponent_get_first_property(comp, ICAL_LOCATION_PROPERTY))) {
229  ast_string_field_set(event, location, icalproperty_get_value_as_string(prop));
230  }
231 
232  if ((prop = icalcomponent_get_first_property(comp, ICAL_CATEGORIES_PROPERTY))) {
233  ast_string_field_set(event, categories, icalproperty_get_value_as_string(prop));
234  }
235 
236  if ((prop = icalcomponent_get_first_property(comp, ICAL_PRIORITY_PROPERTY))) {
237  event->priority = icalvalue_get_integer(icalproperty_get_value(prop));
238  }
239 
240  if ((prop = icalcomponent_get_first_property(comp, ICAL_UID_PROPERTY))) {
241  ast_string_field_set(event, uid, icalproperty_get_value_as_string(prop));
242  } else {
243  ast_log(LOG_WARNING, "No UID found, but one is required. Generating, but updates may not be acurate\n");
244  if (!ast_strlen_zero(event->summary)) {
245  ast_string_field_set(event, uid, event->summary);
246  } else {
247  char tmp[100];
248  snprintf(tmp, sizeof(tmp), "%ld", event->start);
249  ast_string_field_set(event, uid, tmp);
250  }
251  }
252 
253  /* Get the attendees */
254  for (prop = icalcomponent_get_first_property(comp, ICAL_ATTENDEE_PROPERTY);
255  prop; prop = icalcomponent_get_next_property(comp, ICAL_ATTENDEE_PROPERTY)) {
256  struct ast_calendar_attendee *attendee;
257  const char *data;
258 
259  if (!(attendee = ast_calloc(1, sizeof(*attendee)))) {
260  event = ast_calendar_unref_event(event);
261  return;
262  }
263  data = icalproperty_get_attendee(prop);
264  if (ast_strlen_zero(data)) {
265  ast_free(attendee);
266  continue;
267  }
268  attendee->data = ast_strdup(data);;
269  AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
270  }
271 
272 
273  /* Only set values for alarm based on VALARM. Can be overriden in main/calendar.c by autoreminder
274  * therefore, go ahead and add events even if their is no VALARM or it is malformed
275  * Currently we are only getting the first VALARM and are handling repitition in main/calendar.c from calendar.conf */
276  if (!(valarm = icalcomponent_get_first_component(comp, ICAL_VALARM_COMPONENT))) {
277  ao2_link(pvt->events, event);
278  event = ast_calendar_unref_event(event);
279  return;
280  }
281 
282  if (!(prop = icalcomponent_get_first_property(valarm, ICAL_TRIGGER_PROPERTY))) {
283  ast_log(LOG_WARNING, "VALARM has no TRIGGER, skipping!\n");
284  ao2_link(pvt->events, event);
285  event = ast_calendar_unref_event(event);
286  return;
287  }
288 
289  trigger = icalproperty_get_trigger(prop);
290 
291  if (icaltriggertype_is_null_trigger(trigger)) {
292  ast_log(LOG_WARNING, "Bad TRIGGER for VALARM, skipping!\n");
293  ao2_link(pvt->events, event);
294  event = ast_calendar_unref_event(event);
295  return;
296  }
297 
298  if (!icaltime_is_null_time(trigger.time)) { /* This is an absolute time */
299  tmp = icaltime_convert_to_zone(trigger.time, utc);
300  event->alarm = icaltime_as_timet_with_zone(tmp, utc);
301  } else { /* Offset from either dtstart or dtend */
302  /* XXX Technically you can check RELATED to see if the event fires from the END of the event
303  * But, I'm not sure I've ever seen anyone implement it in calendaring software, so I'm ignoring for now */
304  tmp = icaltime_add(start, trigger.duration);
305  event->alarm = icaltime_as_timet_with_zone(tmp, utc);
306  }
307 
308  ao2_link(pvt->events, event);
309  event = ast_calendar_unref_event(event);
310 
311  return;
312 }
struct ast_calendar * owner
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
struct ast_calendar_attendee * next
Definition: calendar.h:89
static time_t icalfloat_to_timet(icaltimetype time)
struct ao2_container * events
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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
#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_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 ast_calendar_event::attendees attendees
icalcomponent * data
#define ast_calloc(a, b)
Definition: astmm.h:82
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 void icalendar_destructor ( void *  obj)
static

Definition at line 70 of file res_calendar_icalendar.c.

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

Referenced by ical_load_calendar().

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  }
82 
83  ao2_callback(pvt->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
84 
85  ao2_ref(pvt->events, -1);
86 }
struct ast_calendar * owner
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
struct ao2_container * events
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const ast_string_field name
Definition: calendar.h:127
icalcomponent * data
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static void icalendar_update_events ( struct icalendar_pvt pvt)
static

Definition at line 314 of file res_calendar_icalendar.c.

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

315 {
316  struct icaltimetype start_time, end_time;
317  icalcomponent *iter;
318 
319  if (!pvt) {
320  ast_log(LOG_ERROR, "iCalendar is NULL\n");
321  return;
322  }
323 
324  if (!pvt->owner) {
325  ast_log(LOG_ERROR, "iCalendar is an orphan!\n");
326  return;
327  }
328 
329  if (!pvt->data) {
330  ast_log(LOG_ERROR, "The iCalendar has not been parsed!\n");
331  return;
332  }
333 
334  start_time = icaltime_current_time_with_zone(icaltimezone_get_utc_timezone());
335  end_time = icaltime_current_time_with_zone(icaltimezone_get_utc_timezone());
336  end_time.second += pvt->owner->timeframe * 60;
337  icaltime_normalize(end_time);
338 
339  for (iter = icalcomponent_get_first_component(pvt->data, ICAL_VEVENT_COMPONENT);
340  iter;
341  iter = icalcomponent_get_next_component(pvt->data, ICAL_VEVENT_COMPONENT))
342  {
343  icalcomponent_foreach_recurrence(iter, start_time, end_time, icalendar_add_event, pvt);
344  }
345 
347 }
struct ast_calendar * owner
static void icalendar_add_event(icalcomponent *comp, struct icaltime_span *span, void *data)
struct ao2_container * events
int timeframe
Definition: calendar.h:131
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.
Definition: res_calendar.c:961
#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
icalcomponent * data
static time_t icalfloat_to_timet ( icaltimetype  time)
static

Definition at line 163 of file res_calendar_icalendar.c.

References ast_mktime(), 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().

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

Definition at line 487 of file res_calendar_icalendar.c.

References ast_calendar_register(), AST_MODULE_LOAD_DECLINE, and AST_MODULE_LOAD_SUCCESS.

488 {
489  ne_sock_init();
491  ne_sock_exit();
493  }
494 
496 }
int ast_calendar_register(struct ast_calendar_tech *tech)
Register a new calendar technology.
Definition: res_calendar.c:490
static struct ast_calendar_tech ical_tech
static int unload_module ( void  )
static

Definition at line 498 of file res_calendar_icalendar.c.

References ast_calendar_unregister().

499 {
501  ne_sock_exit();
502  return 0;
503 }
static struct ast_calendar_tech ical_tech
void ast_calendar_unregister(struct ast_calendar_tech *tech)
Unregister a new calendar technology.
Definition: res_calendar.c:523
static void * unref_icalendar ( void *  obj)
static

Definition at line 88 of file res_calendar_icalendar.c.

References ao2_ref.

Referenced by ical_load_calendar().

89 {
90  struct icalendar_pvt *pvt = obj;
91 
92  ao2_ref(pvt, -1);
93  return NULL;
94 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472

Variable Documentation

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

Definition at line 509 of file res_calendar_icalendar.c.

Definition at line 509 of file res_calendar_icalendar.c.

struct ast_calendar_tech ical_tech
static

Definition at line 49 of file res_calendar_icalendar.c.