nea.h 14.6 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
 * * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#ifndef NEA_H /** Defined when <nea.h> has been included. */
#define NEA_H "$Id: nea.h,v 1.2 2005/08/08 19:10:00 ppessi Exp $"
/**@file nea.h
 * @brief Event API for SIP
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 * @author Martti Mela <Martti.Mela@nokia.com>
 *
 * @date Created: Fri Feb  7 13:23:44 EET 2003 ppessi
 *
 * $Date: 2005/08/08 19:10:00 $
 * 
 */

#if !defined(WIN32)
#define NEA_DLL
#elif defined(NEA_EXPORTS)
#define NEA_DLL __declspec(dllexport)
#else
#define NEA_DLL __declspec(dllimport)
#endif

#ifndef SU_ALLOC_H
#include <su_alloc.h>
#endif

#include <su_tag.h>
#include <su_tag.h>

#ifndef NTA_H
#include <nta.h>
#endif

#define NEA_VERSION      3.0
#define NEA_VERSION_STR "3.0"

#define NEA_DEFAULT_EXPIRES 3600

/** Event notifier object. */
typedef struct nea_server_s     nea_server_t;

/** Subscription object. */
typedef struct nea_sub_s        nea_sub_t;

/** Event. */
typedef struct nea_event_s      nea_event_t;

/** Event view. */
typedef struct nea_event_view_s nea_event_view_t;

#ifndef NEA_SMAGIC_T 
#define NEA_SMAGIC_T            struct nea_smagic_t
#endif
/** NEA server context */
typedef NEA_SMAGIC_T nea_smagic_t;

#ifndef NEA_EMAGIC_T 
#define NEA_EMAGIC_T            struct nea_emagic_t
#endif
/** NEA server event context */
typedef NEA_EMAGIC_T nea_emagic_t;

#ifndef NEA_EVMAGIC_T 
#define NEA_EVMAGIC_T           struct nea_evmagic_t
#endif
/** Event view context */
typedef NEA_EVMAGIC_T nea_evmagic_t;

/** Event states */
typedef enum {
  nea_extended = -1,
  nea_embryonic = 0,		/** Before first notify */
  nea_pending,
  nea_active,
  nea_terminated
} nea_state_t;

/** Description of subscription */
typedef struct nea_subnode_t {
  nea_state_t          sn_state;       	/**< Subscription state */
  unsigned             sn_fake;	       	/**< True if subscriber is given 
				       	 *   fake contents.
				       	 */
  unsigned             sn_eventlist;    /**< Subscriber supports eventlist */
  nea_sub_t           *sn_subscriber;  	/**< Pointer to subscriber object */
  nea_event_t         *sn_event;       	/**< Event */
  sip_from_t const    *sn_remote;      	/**< Identity of subscriber */
  sip_contact_t const *sn_contact;     	/**< Contact of subscriber */

  /** Content-Type of SUBSCRIBE body (filter). */
  sip_content_type_t const *sn_content_type; 
  sip_payload_t const *sn_payload;      /**< Body of subscribe*/

  unsigned             sn_expires;     	/**< When subscription expires */
  unsigned             sn_latest;      	/**< Latest notification version */
  unsigned             sn_throttle;    	/**< Throttle value */
  unsigned             sn_version;      /**< Version # by application */
  sip_time_t           sn_notified;     /**< When latest notify was sent */
  sip_time_t           sn_subscribed;   /**< When first SUBSCRIBE was recv */
  nea_event_view_t    *sn_view;		/**< Primary event view */
} nea_subnode_t;

/** Multiple content types per event. */
typedef struct nea_payloads_s   nea_payloads_t;

/**Unknown event callback.
 *
 * The event server invokes this callback function when it has received a
 * request for an unknown event or event with unknown content type.
 *
 * The callback may be called twice for one watcher, once for an unknown
 * event, another time for an unknown content type.
 *
 * @retval 1 application takes care of responding to request
 * @retval 0 application has added new event or payload format
 * @retval -1 nea server rejects request 
 */
typedef int (nea_new_event_f)(nea_smagic_t *context,
			      nea_server_t *nes,
			      nea_event_t **event_p,
			      nea_event_view_t **view_p,
			      nta_incoming_t *irq,
			      sip_t const *sip);

/** Create a notifier server */
nea_server_t *nea_server_create(nta_agent_t *agent,
				su_root_t *root,
				url_t const *url,
				int max_subs,
				nea_new_event_f *callback,
				nea_smagic_t *context,
				tag_type_t tag, tag_value_t value,
				...);

/** Specify the minimum duration of a subscription (by default, 15 minutes) */
#define NEATAG_MIN_EXPIRES(x) neatag_min_expires, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_min_expires;

#define NEATAG_MIN_EXPIRES_REF(x) neatag_min_expires_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_min_expires_ref;

#define NEATAG_MINSUB(x) neatag_min_expires, tag_uint_v((x))
#define NEATAG_MINSUB_REF(x) neatag_min_expires_ref, tag_uint_vr((&x))

/** Specify the default duration of a subscription (by default, 60 minutes) */
#define NEATAG_EXPIRES(x) neatag_expires, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_expires;

#define NEATAG_EXPIRES_REF(x) neatag_expires_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_expires_ref;

/** Specify the maximum duration of a subscription (by default, 24 hours) */
#define NEATAG_MAX_EXPIRES(x) neatag_max_expires, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_max_expires;

#define NEATAG_MAX_EXPIRES_REF(x) neatag_max_expires_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_max_expires_ref;

/** Indicate/require support for "eventlist" feature. */
#define NEATAG_EVENTLIST(x)  neatag_eventlist, tag_bool_v((x))
NEA_DLL extern tag_typedef_t neatag_eventlist;

#define NEATAG_EVENTLIST_REF(x) neatag_eventlist_ref, tag_bool_vr((&x))
NEA_DLL extern tag_typedef_t neatag_eventlist_ref;

/** Specify the default throttle value for subscription. */
#define NEATAG_THROTTLE(x) neatag_throttle, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_throttle;

#define NEATAG_THROTTLE_REF(x) neatag_throttle_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_throttle_ref;

/** Specify the minimum throttle value for subscription. */
#define NEATAG_MINTHROTTLE(x) neatag_minthrottle, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_minthrottle;

#define NEATAG_MINTHROTTLE_REF(x) neatag_minthrottle_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_minthrottle_ref;

/** Specify dialog handle */
#define NEATAG_DIALOG(x)     neatag_dialog, tag_ptr_v((x))
NEA_DLL extern tag_typedef_t neatag_dialog;

#define NEATAG_DIALOG_REF(x) neatag_dialog_ref, tag_ptr_vr((&x), (x))
NEA_DLL extern tag_typedef_t neatag_dialog_ref;

/** Shutdown an event server */
int nea_server_shutdown(nea_server_t *nes, int retry_after);

/** Destroy a server */
void nea_server_destroy(nea_server_t *nes);

/** Zap terminated subscribtions. */
void nea_server_flush(nea_server_t *nes, nea_event_t *event);

/** Update event information */
int nea_server_update(nea_server_t *nes,
		      nea_event_t *ev,
		      tag_type_t tag,
		      tag_value_t value,
		      ...);

/** Add a new subscriber to existing notifier */
int nea_server_add(nea_server_t *nes, 
		   sip_contact_t const *local_target,
		   msg_t *msg, 
		   sip_t *sip);

/** Add a new subscriber to existing notifier. */
int nea_server_add_irq(nea_server_t *nes,
		       nta_leg_t *leg,
		       sip_contact_t const *local_target,
		       nta_incoming_t *irq, 
		       sip_t const *sip);

/** QAUTH callback function type.
 *
 * The event server invokes this callback function upon each incoming
 * SUBSCRIBE transaction when the subscription has expired.  The @a sip is
 * NULL if the subscription has expired.
 *
 * The application determines if the subscription is authorized and relays
 * the decision to event server via nea_server_auth() function.
 */
typedef void (nea_watcher_f)(nea_server_t *nes,
			     nea_emagic_t *context,
			     nea_event_t *event,
			     nea_subnode_t *subnode,
			     sip_t const *sip);

/** Create a new event (or subevent) */
nea_event_t *nea_event_create(nea_server_t *nes,
			      nea_watcher_f *callback,
			      nea_emagic_t *context,
			      char const *name, 
			      char const *subname,
			      char const *default_content_type,
			      char const *accept);

/** Create a new event (or subevent) with tags */
nea_event_t *nea_event_tcreate(nea_server_t *nes,
			       nea_watcher_f *callback,
			       nea_emagic_t *context,
			       char const *name, 
			       char const *subname,
			       tag_type_t, tag_value_t, ...);

/** Return magic context bind to nea_event */
nea_emagic_t *nea_emagic_get(nea_event_t *event);

/** Find a nea event object with given event name */
nea_event_t *nea_event_get(nea_server_t const *nes, char const *name);

/** Get number of active subscribers */
int nea_server_active(nea_server_t *nes, nea_event_t const *ev);

/** Get number of (non-embryonic) subscribers. */
int nea_server_non_embryonic(nea_server_t *nes, nea_event_t const *ev);

/** Obtain a list of subscriptions. 
 */
nea_subnode_t const **nea_server_get_subscribers(nea_server_t *nes, 
						 nea_event_t const *ev);

/** Free a list of subscriptions. */
void nea_server_free_subscribers(nea_server_t *nes, nea_subnode_t const **);

/** Notify subscribers */
int nea_server_notify(nea_server_t *nes, 
		      nea_event_t *ev);

/** Notify a subscriber */
int nea_server_notify_one(nea_server_t *nes, 
			  nea_event_t *ev,
			  nea_sub_t *ns);

#define nea_server_auth nea_sub_auth

/** Authorize a subscription */
int nea_sub_auth(nea_sub_t *, nea_state_t state,
		 tag_type_t, tag_value_t, ...);

/** Set subscriber version sequence */
int nea_sub_version(nea_sub_t *, unsigned);

/** Return time until next notification can be sent */
unsigned nea_sub_pending(nea_sub_t const *);

/** Send fake content for this subscriber */
#define NEATAG_FAKE(x)    neatag_fake, tag_bool_v((x))
NEA_DLL extern tag_typedef_t neatag_fake;

#define NEATAG_FAKE_REF(x) neatag_fake_ref, tag_bool_vr((&x))
NEA_DLL extern tag_typedef_t neatag_fake_ref;

/** Specify reason for termination */
#define NEATAG_REASON(x)     neatag_reason, tag_str_v((x))
NEA_DLL extern tag_typedef_t neatag_reason;

#define NEATAG_REASON_REF(x) neatag_reason_ref, tag_str_vr((&x))
NEA_DLL extern tag_typedef_t neatag_reason_ref;

/** Specify retry-after for termination */
#define NEATAG_RETRY_AFTER(x)    neatag_retry_after, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_retry_after;

#define NEATAG_RETRY_AFTER_REF(x) neatag_retry_after_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_retry_after_ref;

/** Specify extended state for subscription-state */
#define NEATAG_EXSTATE(x)    neatag_exstate, tag_str_v((x))
NEA_DLL extern tag_typedef_t neatag_exstate;

#define NEATAG_EXSTATE_REF(x) neatag_exstate_ref, tag_str_vr((&x))
NEA_DLL extern tag_typedef_t neatag_exstate_ref;

/** Do not try to conform pre-3265 notifiers/watchers */
#define NEATAG_STRICT_3265(x)    neatag_strict_3265, tag_bool_v((x))
NEA_DLL extern tag_typedef_t neatag_strict_3265;

#define NEATAG_STRICT_3265_REF(x) neatag_strict_3265_ref, tag_bool_vr((&x))
NEA_DLL extern tag_typedef_t neatag_strict_3265_ref;

/** Version number of content */
#define NEATAG_VERSION(x) neatag_version, tag_uint_v((x))
NEA_DLL extern tag_typedef_t neatag_version;

#define NEATAG_VERSION_REF(x) neatag_version_ref, tag_uint_vr((&x))
NEA_DLL extern tag_typedef_t neatag_version_ref;

#if 0
/** Do a remote qauth.
 *
 * The function nea_server_qauth() is given as q_callback pointer 
 * to nea_server_create() if remote authentication from url is desired.
 */
void nea_server_qauth(nea_server_t *nes, 
		      nea_emagic_t *context,
		      nea_sub_t *subscriber, 
		      sip_t const *sip);
#endif

/** Get primary event view for given content type  */
nea_event_view_t *nea_event_view(nea_event_t *, char const *content_type);

/** Get a content type for event's payload */
sip_content_type_t const *nea_view_content_type(nea_event_view_t const *);

/** Get actual payload for an event */
sip_payload_t const *nea_view_payload(nea_event_view_t *);

/** Create a private event view */
nea_event_view_t *nea_view_create(nea_server_t *nes,
				  nea_event_t *ev,
				  nea_evmagic_t *magic,
				  tag_type_t tag,
				  tag_value_t value,
				  ...);

/** Destroy a private event view */
void nea_view_destroy(nea_server_t *nes, nea_event_view_t *ev);

nea_evmagic_t *nea_view_magic(nea_event_view_t const *);

void nea_view_set_magic(nea_event_view_t *evv, nea_evmagic_t *magic);

unsigned nea_view_version(nea_event_view_t const *);

/** Reliable notify */
#define NEATAG_RELIABLE(x)    neatag_reliable, tag_bool_v((x))
NEA_DLL extern tag_typedef_t neatag_reliable;

#define NEATAG_RELIABLE_REF(x) neatag_reliable_ref, tag_bool_vr((&x))
NEA_DLL extern tag_typedef_t neatag_reliable_ref;

/** Event view handle */
#define NEATAG_VIEW(x)     neatag_view, tag_ptr_v((x))
NEA_DLL extern tag_typedef_t neatag_view;

#define NEATAG_VIEW_REF(x) neatag_view_ref, tag_ptr_vr((&x), (x))
NEA_DLL extern tag_typedef_t neatag_view_ref;

/** Event view magic. */
#define NEATAG_EVMAGIC(x)     neatag_evmagic, tag_ptr_v((x))
NEA_DLL extern tag_typedef_t neatag_evmagic;

#define NEATAG_EVMAGIC_REF(x) neatag_evmagic_ref, tag_ptr_vr((&x), (x))
NEA_DLL extern tag_typedef_t neatag_evmagic_ref;

/* ====================================================================== */
/* Watcher side */

/** NEA Event Watcher */
typedef struct nea_s     nea_t;

#ifndef NEA_MAGIC_T 
#define NEA_MAGIC_T struct nea_magic_t
#endif

/** NEA Event Agent context */
typedef NEA_MAGIC_T          nea_magic_t;

/** Event notification callback type.
 * 
 * This callback is called also when initial or refresh subscribe transaction
 * completes with the transaction result in @a sip.
 */
typedef int (*nea_notify_f)(nea_t *nea,
			    nea_magic_t *context,
			    sip_t const *sip);

/* ====================================================================== */
/* Client side */

/** Create a subscription agent. */
nea_t *nea_create(nta_agent_t *agent,
		  su_root_t *root,
		  nea_notify_f no_callback,
		  nea_magic_t *context,
		  tag_type_t tag,
		  tag_value_t value,
		  ...);

/** Update SUBSCRIBE payload (filter rules) */
extern int nea_update(nea_t *nea, 
		      tag_type_t tag,
		      tag_value_t value,
		      ...);

/** Unsubscribe agent. */
void nea_end(nea_t *agent);

/** Destroy a subscription agent. */
void nea_destroy(nea_t *agent);

char const *nea_default_content_type(char const *event);

#endif /* !defined(NEA_H) */