blob: 25ad4891fb20cb17653632b4d389864deec2af08 [file] [log] [blame]
Benny Prijono834aee32006-02-19 01:38:06 +00001/* $Id$ */
2/*
Benny Prijono32177c02008-06-20 22:44:47 +00003 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono834aee32006-02-19 01:38:06 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#ifndef __PJSIP_SIMPLE_EVSUB_H__
20#define __PJSIP_SIMPLE_EVSUB_H__
21
22/**
Benny Prijonoa7b376b2008-01-25 16:06:33 +000023 * @file evsub.h
Benny Prijono834aee32006-02-19 01:38:06 +000024 * @brief SIP Specific Event Notification Extension (RFC 3265)
25 */
26
27#include <pjsip-simple/types.h>
28
29
30/**
31 * @defgroup PJSIP_EVENT_NOT SIP Event Notification (RFC 3265) Module
32 * @ingroup PJSIP_SIMPLE
Benny Prijono312aff92006-06-17 04:08:30 +000033 * @brief Core Event Subscription framework, used by presence, call transfer, etc.
Benny Prijono834aee32006-02-19 01:38:06 +000034 * @{
35 *
36 * This module provides the implementation of SIP Extension for SIP Specific
37 * Event Notification (RFC 3265). It extends PJSIP by supporting SUBSCRIBE and
38 * NOTIFY methods.
39 *
40 * This module itself is extensible; new event packages can be registered to
41 * this module to handle specific extensions (such as presence).
42 */
43
44PJ_BEGIN_DECL
45
46
47/**
48 * Opaque type for event subscription session.
49 */
50typedef struct pjsip_evsub pjsip_evsub;
51
52
53/**
54 * This enumeration describes basic subscription state as described in the
55 * RFC 3265. The standard specifies that extensions may define additional
56 * states. In the case where the state is not known, the subscription state
57 * will be set to PJSIP_EVSUB_STATE_UNKNOWN, and the token will be kept
58 * in state_str member of the susbcription structure.
59 */
60enum pjsip_evsub_state
61{
62 PJSIP_EVSUB_STATE_NULL, /**< State is NULL. */
63 PJSIP_EVSUB_STATE_SENT, /**< Client has sent SUBSCRIBE request. */
64 PJSIP_EVSUB_STATE_ACCEPTED, /**< 2xx response to SUBSCRIBE has been
65 sent/received. */
66 PJSIP_EVSUB_STATE_PENDING, /**< Subscription is pending. */
67 PJSIP_EVSUB_STATE_ACTIVE, /**< Subscription is active. */
68 PJSIP_EVSUB_STATE_TERMINATED,/**< Subscription is terminated. */
69 PJSIP_EVSUB_STATE_UNKNOWN, /**< Subscription state can not be determined.
70 Application can query the state by
71 calling #pjsip_evsub_get_state_name().*/
72};
73
74/**
75 * @see pjsip_evsub_state
76 */
77typedef enum pjsip_evsub_state pjsip_evsub_state;
78
79
Benny Prijono26ff9062006-02-21 23:47:00 +000080/**
81 * Some options for the event subscription.
82 */
83enum
84{
85 /**
86 * If this flag is set, then outgoing request to create subscription
87 * will not have id in the Event header (e.g. in REFER request). But if
88 * there is an id in the incoming NOTIFY, that id will be used.
89 */
90 PJSIP_EVSUB_NO_EVENT_ID = 1,
91};
92
Benny Prijono834aee32006-02-19 01:38:06 +000093
94/**
95 * This structure describes callback that is registered by application or
96 * package to receive notifications about subscription events.
97 */
98struct pjsip_evsub_user
99{
100 /**
101 * This callback is called when subscription state has changed.
102 * Application MUST be prepared to receive NULL event and events with
103 * type other than PJSIP_EVENT_TSX_STATE
104 *
105 * This callback is OPTIONAL.
106 *
107 * @param sub The subscription instance.
108 * @param event The event that has caused the state to change,
109 * which may be NULL or may have type other than
110 * PJSIP_EVENT_TSX_STATE.
111 */
112 void (*on_evsub_state)( pjsip_evsub *sub, pjsip_event *event);
113
114 /**
115 * This callback is called when transaction state has changed.
116 *
117 * @param sub The subscription instance.
118 * @param tsx Transaction.
119 * @param event The event.
120 */
121 void (*on_tsx_state)(pjsip_evsub *sub, pjsip_transaction *tsx,
122 pjsip_event *event);
123
124 /**
125 * This callback is called when incoming SUBSCRIBE (or any method that
126 * establishes the subscription in the first place) is received. It
127 * allows application to specify what response should be sent to
128 * remote, along with additional headers and message body to be put
129 * in the response.
130 *
131 * This callback is OPTIONAL.
132 *
133 * However, implementation MUST send NOTIFY request upon receiving this
134 * callback. The suggested behavior is to call
Benny Prijonoa7b376b2008-01-25 16:06:33 +0000135 * #pjsip_evsub_current_notify(), since this function takes care
Benny Prijono834aee32006-02-19 01:38:06 +0000136 * about unsubscription request and calculates the appropriate expiration
137 * interval.
138 */
139 void (*on_rx_refresh)( pjsip_evsub *sub,
140 pjsip_rx_data *rdata,
141 int *p_st_code,
142 pj_str_t **p_st_text,
143 pjsip_hdr *res_hdr,
144 pjsip_msg_body **p_body);
145
146 /**
147 * This callback is called when client/subscriber received incoming
148 * NOTIFY request. It allows the application to specify what response
149 * should be sent to remote, along with additional headers and message
150 * body to be put in the response.
151 *
152 * This callback is OPTIONAL. When it is not implemented, the default
153 * behavior is to respond incoming NOTIFY request with 200 (OK).
154 *
155 * @param sub The subscription instance.
156 * @param rdata The received NOTIFY request.
157 * @param p_st_code Application MUST set the value of this argument with
158 * final status code (200-699) upon returning from the
159 * callback.
160 * @param p_st_text Custom status text, if any.
161 * @param res_hdr Upon return, application can put additional headers
162 * to be sent in the response in this list.
163 * @param p_body Application MAY specify message body to be sent in
164 * the response.
165 */
166 void (*on_rx_notify)(pjsip_evsub *sub,
167 pjsip_rx_data *rdata,
168 int *p_st_code,
169 pj_str_t **p_st_text,
170 pjsip_hdr *res_hdr,
171 pjsip_msg_body **p_body);
172
173 /**
174 * This callback is called when it is time for the client to refresh
175 * the subscription.
176 *
Benny Prijono8c715612006-02-25 02:04:42 +0000177 * This callback is OPTIONAL when PJSIP package such as presence or
178 * refer is used; the event package will refresh subscription by sending
179 * SUBSCRIBE with the interval set to current/last interval.
Benny Prijono834aee32006-02-19 01:38:06 +0000180 *
181 * @param sub The subscription instance.
182 */
183 void (*on_client_refresh)(pjsip_evsub *sub);
184
185 /**
186 * This callback is called when server doesn't receive subscription
187 * refresh after the specified subscription interval.
188 *
Benny Prijono8c715612006-02-25 02:04:42 +0000189 * This callback is OPTIONAL when PJSIP package such as presence or
190 * refer is used; the event package send NOTIFY to terminate the
191 * subscription.
Benny Prijono834aee32006-02-19 01:38:06 +0000192 */
193 void (*on_server_timeout)(pjsip_evsub *sub);
194
195};
196
197
198/**
199 * @see pjsip_evsub_user
200 */
201typedef struct pjsip_evsub_user pjsip_evsub_user;
202
203
204/**
Benny Prijono1f61a8f2007-08-16 10:11:44 +0000205 * SUBSCRIBE method constant. @see pjsip_get_subscribe_method()
206 */
207PJ_DECL_DATA(const pjsip_method) pjsip_subscribe_method;
208
209/**
210 * NOTIFY method constant. @see pjsip_get_notify_method()
211 */
212PJ_DECL_DATA(const pjsip_method) pjsip_notify_method;
213
214/**
Benny Prijono834aee32006-02-19 01:38:06 +0000215 * SUBSCRIBE method constant.
216 */
Benny Prijono90cc76e2008-07-11 00:56:07 +0000217PJ_DECL(const pjsip_method*) pjsip_get_subscribe_method(void);
Benny Prijono834aee32006-02-19 01:38:06 +0000218
219/**
220 * NOTIFY method constant.
221 */
Benny Prijono90cc76e2008-07-11 00:56:07 +0000222PJ_DECL(const pjsip_method*) pjsip_get_notify_method(void);
Benny Prijono834aee32006-02-19 01:38:06 +0000223
224
225/**
226 * Initialize the event subscription module and register the module to the
227 * specified endpoint.
228 *
229 * @param endpt The endpoint instance.
230 *
231 * @return PJ_SUCCESS if module can be created and registered
232 * successfully.
233 */
234PJ_DECL(pj_status_t) pjsip_evsub_init_module(pjsip_endpoint *endpt);
235
236
237/**
238 * Get the event subscription module instance that was previously created
239 * and registered to endpoint.
240 *
241 * @return The event subscription module instance.
242 */
243PJ_DECL(pjsip_module*) pjsip_evsub_instance(void);
244
245
246/**
247 * Register event package to the event subscription framework.
248 *
249 * @param pkg_mod The module that implements the event package being
250 * registered.
251 * @param event_name Event package identification.
252 * @param expires Default subscription expiration time, in seconds.
253 * @param accept_cnt Number of strings in Accept array.
254 * @param accept Array of Accept value.
255 *
256 * @return PJ_SUCCESS on success.
257 */
258PJ_DECL(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
259 const pj_str_t *event_name,
260 unsigned expires,
261 unsigned accept_cnt,
262 const pj_str_t accept[]);
263
Benny Prijono56315612006-07-18 14:39:40 +0000264/**
265 * Get the Allow-Events header. This header is built based on the packages
266 * that are registered to the evsub module.
267 *
268 * @param m Pointer to event subscription module instance, or
269 * NULL to use default instance (equal to
270 * #pjsip_evsub_instance()).
271 *
272 * @return The Allow-Events header.
273 */
274PJ_DECL(const pjsip_hdr*) pjsip_evsub_get_allow_events_hdr(pjsip_module *m);
275
Benny Prijono834aee32006-02-19 01:38:06 +0000276
277/**
278 * Create client subscription session.
279 *
280 * @param dlg The underlying dialog to use.
281 * @param user_cb Callback to receive event subscription notifications.
282 * @param event Event name.
Benny Prijono26ff9062006-02-21 23:47:00 +0000283 * @param option Bitmask of options.
Benny Prijono834aee32006-02-19 01:38:06 +0000284 * @param p_evsub Pointer to receive event subscription instance.
285 *
286 * @return PJ_SUCCESS on success.
287 */
288PJ_DECL(pj_status_t) pjsip_evsub_create_uac( pjsip_dialog *dlg,
289 const pjsip_evsub_user *user_cb,
290 const pj_str_t *event,
Benny Prijono26ff9062006-02-21 23:47:00 +0000291 unsigned option,
Benny Prijono834aee32006-02-19 01:38:06 +0000292 pjsip_evsub **p_evsub);
293
294/**
295 * Create server subscription session.
296 *
297 * @param dlg The underlying dialog to use.
298 * @param user_cb Callback to receive event subscription notifications.
299 * @param rdata The incoming request that creates the event
300 * subscription, such as SUBSCRIBE or REFER.
Benny Prijono26ff9062006-02-21 23:47:00 +0000301 * @param option Bitmask of options.
Benny Prijono834aee32006-02-19 01:38:06 +0000302 * @param p_evsub Pointer to receive event subscription instance.
303 *
304 * @return PJ_SUCCESS on success.
305 */
306PJ_DECL(pj_status_t) pjsip_evsub_create_uas( pjsip_dialog *dlg,
307 const pjsip_evsub_user *user_cb,
308 pjsip_rx_data *rdata,
Benny Prijono26ff9062006-02-21 23:47:00 +0000309 unsigned option,
Benny Prijono834aee32006-02-19 01:38:06 +0000310 pjsip_evsub **p_evsub);
311
Benny Prijonod4e0abd2006-03-05 11:53:36 +0000312/**
313 * Forcefully destroy the subscription session. This function should only
314 * be called on special condition, such as when the subscription
315 * initialization has failed. For other conditions, application MUST terminate
316 * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.
317 *
318 * @param sub The event subscription.
319 * @param notify Specify whether the state notification callback
320 * should be called.
321 *
322 * @return PJ_SUCCESS if subscription session has been destroyed.
323 */
324PJ_DECL(pj_status_t) pjsip_evsub_terminate( pjsip_evsub *sub,
325 pj_bool_t notify );
326
Benny Prijono834aee32006-02-19 01:38:06 +0000327
328/**
329 * Get subscription state.
330 *
331 * @param sub Event subscription instance.
332 *
333 * @return Subscription state.
334 */
335PJ_DECL(pjsip_evsub_state) pjsip_evsub_get_state(pjsip_evsub *sub);
336
337
338/**
339 * Get the string representation of the subscription state.
340 *
341 * @param sub Event subscription instance.
342 *
343 * @return NULL terminated string.
344 */
345PJ_DECL(const char*) pjsip_evsub_get_state_name(pjsip_evsub *sub);
346
347
348/**
349 * Call this function to create request to initiate subscription, to
350 * refresh subcription, or to request subscription termination.
351 *
352 * @param sub Client subscription instance.
353 * @param method The method that establishes the subscription, such as
354 * SUBSCRIBE or REFER. If this argument is NULL, then
355 * SUBSCRIBE will be used.
356 * @param expires Subscription expiration. If the value is set to zero,
357 * this will request unsubscription. If the value is
358 * negative, default expiration as defined by the package
359 * will be used.
360 * @param p_tdata Pointer to receive the request.
361 *
362 * @return PJ_SUCCESS on success.
363 */
364PJ_DECL(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,
365 const pjsip_method *method,
366 pj_int32_t expires,
367 pjsip_tx_data **p_tdata);
368
369
370/**
371 * Accept the incoming subscription request by sending 2xx response to
372 * incoming SUBSCRIBE request.
373 *
374 * @param sub Server subscription instance.
375 * @param rdata The incoming subscription request message.
376 * @param st_code Status code, which MUST be final response.
377 * @param hdr_list Optional list of headers to be added in the response.
378 *
379 * @return PJ_SUCCESS on success.
380 */
381PJ_DECL(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,
382 pjsip_rx_data *rdata,
383 int st_code,
384 const pjsip_hdr *hdr_list );
385
386
387/**
388 * For notifier, create NOTIFY request to subscriber, and set the state
389 * of the subscription.
390 *
391 * @param sub The server subscription (notifier) instance.
392 * @param state New state to set.
393 * @param state_str The state string name, if state contains value other
394 * than active, pending, or terminated. Otherwise this
395 * argument is ignored.
396 * @param reason Specify reason if new state is terminated, otherwise
397 * put NULL.
398 * @param p_tdata Pointer to receive request message.
399 *
400 * @return PJ_SUCCESS on success.
401 */
402PJ_DECL(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,
403 pjsip_evsub_state state,
404 const pj_str_t *state_str,
405 const pj_str_t *reason,
406 pjsip_tx_data **p_tdata);
407
408
409/**
410 * For notifier, create a NOTIFY request that reflects current subscription
411 * status.
412 *
413 * @param sub The server subscription instance.
414 * @param p_tdata Pointer to receive the request messge.
415 *
416 * @return PJ_SUCCESS on success.
417 */
418PJ_DECL(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,
419 pjsip_tx_data **p_tdata );
420
421
422
423/**
Benny Prijono26ff9062006-02-21 23:47:00 +0000424 * Send request message that was previously created with initiate(), notify(),
425 * or current_notify(). Application may also send request created with other
426 * functions, e.g. authentication. But the request MUST be either request
427 * that creates/refresh subscription or NOTIFY request.
Benny Prijono834aee32006-02-19 01:38:06 +0000428 *
429 * @param sub The event subscription object.
430 * @param tdata Request message to be send.
431 *
432 * @return PJ_SUCCESS on success.
433 */
434PJ_DECL(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,
435 pjsip_tx_data *tdata);
436
437
438
439/**
Benny Prijono8c715612006-02-25 02:04:42 +0000440 * Get the event subscription instance associated with the specified
441 * transaction.
Benny Prijono834aee32006-02-19 01:38:06 +0000442 *
443 * @param tsx The transaction.
444 *
445 * @return The event subscription instance registered in the
446 * transaction, if any.
447 */
448PJ_DECL(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx);
449
450
451/**
452 * Set event subscription's module data.
453 *
454 * @param sub The event subscription.
Benny Prijono312aff92006-06-17 04:08:30 +0000455 * @param mod_id The module id.
Benny Prijono834aee32006-02-19 01:38:06 +0000456 * @param data Arbitrary data.
457 */
458PJ_DECL(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,
459 void *data );
460
461
462/**
463 * Get event subscription's module data.
464 *
465 * @param sub The event subscription.
466 * @param mod_id The module id.
467 *
468 * @return Data previously set at the specified id.
469 */
470PJ_DECL(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id );
471
472
473
474PJ_END_DECL
475
476/**
477 * @}
478 */
479
480#endif /* __PJSIP_SIMPLE_EVSUB_H__ */