blob: 25a20b1294be3f0735c8d4695d72eb882964651b [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/**
Benny Prijono75130572008-07-17 13:53:41 +0000349 * Get subscription termination reason, if any. If remote did not
350 * send termination reason, this function will return empty string.
351 *
352 * @param sub Event subscription instance.
353 *
354 * @return NULL terminated string.
355 */
356PJ_DECL(const pj_str_t*) pjsip_evsub_get_termination_reason(pjsip_evsub *sub);
357
358
359/**
Benny Prijono834aee32006-02-19 01:38:06 +0000360 * Call this function to create request to initiate subscription, to
361 * refresh subcription, or to request subscription termination.
362 *
363 * @param sub Client subscription instance.
364 * @param method The method that establishes the subscription, such as
365 * SUBSCRIBE or REFER. If this argument is NULL, then
366 * SUBSCRIBE will be used.
367 * @param expires Subscription expiration. If the value is set to zero,
368 * this will request unsubscription. If the value is
369 * negative, default expiration as defined by the package
370 * will be used.
371 * @param p_tdata Pointer to receive the request.
372 *
373 * @return PJ_SUCCESS on success.
374 */
375PJ_DECL(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,
376 const pjsip_method *method,
377 pj_int32_t expires,
378 pjsip_tx_data **p_tdata);
379
380
381/**
382 * Accept the incoming subscription request by sending 2xx response to
383 * incoming SUBSCRIBE request.
384 *
385 * @param sub Server subscription instance.
386 * @param rdata The incoming subscription request message.
387 * @param st_code Status code, which MUST be final response.
388 * @param hdr_list Optional list of headers to be added in the response.
389 *
390 * @return PJ_SUCCESS on success.
391 */
392PJ_DECL(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,
393 pjsip_rx_data *rdata,
394 int st_code,
395 const pjsip_hdr *hdr_list );
396
397
398/**
399 * For notifier, create NOTIFY request to subscriber, and set the state
400 * of the subscription.
401 *
402 * @param sub The server subscription (notifier) instance.
403 * @param state New state to set.
404 * @param state_str The state string name, if state contains value other
405 * than active, pending, or terminated. Otherwise this
406 * argument is ignored.
407 * @param reason Specify reason if new state is terminated, otherwise
408 * put NULL.
409 * @param p_tdata Pointer to receive request message.
410 *
411 * @return PJ_SUCCESS on success.
412 */
413PJ_DECL(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,
414 pjsip_evsub_state state,
415 const pj_str_t *state_str,
416 const pj_str_t *reason,
417 pjsip_tx_data **p_tdata);
418
419
420/**
421 * For notifier, create a NOTIFY request that reflects current subscription
422 * status.
423 *
424 * @param sub The server subscription instance.
425 * @param p_tdata Pointer to receive the request messge.
426 *
427 * @return PJ_SUCCESS on success.
428 */
429PJ_DECL(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,
430 pjsip_tx_data **p_tdata );
431
432
433
434/**
Benny Prijono26ff9062006-02-21 23:47:00 +0000435 * Send request message that was previously created with initiate(), notify(),
436 * or current_notify(). Application may also send request created with other
437 * functions, e.g. authentication. But the request MUST be either request
438 * that creates/refresh subscription or NOTIFY request.
Benny Prijono834aee32006-02-19 01:38:06 +0000439 *
440 * @param sub The event subscription object.
441 * @param tdata Request message to be send.
442 *
443 * @return PJ_SUCCESS on success.
444 */
445PJ_DECL(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,
446 pjsip_tx_data *tdata);
447
448
449
450/**
Benny Prijono8c715612006-02-25 02:04:42 +0000451 * Get the event subscription instance associated with the specified
452 * transaction.
Benny Prijono834aee32006-02-19 01:38:06 +0000453 *
454 * @param tsx The transaction.
455 *
456 * @return The event subscription instance registered in the
457 * transaction, if any.
458 */
459PJ_DECL(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx);
460
461
462/**
463 * Set event subscription's module data.
464 *
465 * @param sub The event subscription.
Benny Prijono312aff92006-06-17 04:08:30 +0000466 * @param mod_id The module id.
Benny Prijono834aee32006-02-19 01:38:06 +0000467 * @param data Arbitrary data.
468 */
469PJ_DECL(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,
470 void *data );
471
472
473/**
474 * Get event subscription's module data.
475 *
476 * @param sub The event subscription.
477 * @param mod_id The module id.
478 *
479 * @return Data previously set at the specified id.
480 */
481PJ_DECL(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id );
482
483
484
485PJ_END_DECL
486
487/**
488 * @}
489 */
490
491#endif /* __PJSIP_SIMPLE_EVSUB_H__ */