blob: 4eb2ae1ce195e40cc69743d9e73e33f28b7281eb [file] [log] [blame]
Benny Prijono834aee32006-02-19 01:38:06 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
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/**
23 * @file event_notify.h
24 * @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
135 * #pjsip_evsub_last_notify(), since this function takes care
136 * 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/**
205 * SUBSCRIBE method constant.
206 */
207extern const pjsip_method pjsip_subscribe_method;
208
209/**
210 * NOTIFY method constant.
211 */
212extern const pjsip_method pjsip_notify_method;
213
214
215
216/**
217 * Initialize the event subscription module and register the module to the
218 * specified endpoint.
219 *
220 * @param endpt The endpoint instance.
221 *
222 * @return PJ_SUCCESS if module can be created and registered
223 * successfully.
224 */
225PJ_DECL(pj_status_t) pjsip_evsub_init_module(pjsip_endpoint *endpt);
226
227
228/**
229 * Get the event subscription module instance that was previously created
230 * and registered to endpoint.
231 *
232 * @return The event subscription module instance.
233 */
234PJ_DECL(pjsip_module*) pjsip_evsub_instance(void);
235
236
237/**
238 * Register event package to the event subscription framework.
239 *
240 * @param pkg_mod The module that implements the event package being
241 * registered.
242 * @param event_name Event package identification.
243 * @param expires Default subscription expiration time, in seconds.
244 * @param accept_cnt Number of strings in Accept array.
245 * @param accept Array of Accept value.
246 *
247 * @return PJ_SUCCESS on success.
248 */
249PJ_DECL(pj_status_t) pjsip_evsub_register_pkg( pjsip_module *pkg_mod,
250 const pj_str_t *event_name,
251 unsigned expires,
252 unsigned accept_cnt,
253 const pj_str_t accept[]);
254
255
256/**
257 * Create client subscription session.
258 *
259 * @param dlg The underlying dialog to use.
260 * @param user_cb Callback to receive event subscription notifications.
261 * @param event Event name.
Benny Prijono26ff9062006-02-21 23:47:00 +0000262 * @param option Bitmask of options.
Benny Prijono834aee32006-02-19 01:38:06 +0000263 * @param p_evsub Pointer to receive event subscription instance.
264 *
265 * @return PJ_SUCCESS on success.
266 */
267PJ_DECL(pj_status_t) pjsip_evsub_create_uac( pjsip_dialog *dlg,
268 const pjsip_evsub_user *user_cb,
269 const pj_str_t *event,
Benny Prijono26ff9062006-02-21 23:47:00 +0000270 unsigned option,
Benny Prijono834aee32006-02-19 01:38:06 +0000271 pjsip_evsub **p_evsub);
272
273/**
274 * Create server subscription session.
275 *
276 * @param dlg The underlying dialog to use.
277 * @param user_cb Callback to receive event subscription notifications.
278 * @param rdata The incoming request that creates the event
279 * subscription, such as SUBSCRIBE or REFER.
Benny Prijono26ff9062006-02-21 23:47:00 +0000280 * @param option Bitmask of options.
Benny Prijono834aee32006-02-19 01:38:06 +0000281 * @param p_evsub Pointer to receive event subscription instance.
282 *
283 * @return PJ_SUCCESS on success.
284 */
285PJ_DECL(pj_status_t) pjsip_evsub_create_uas( pjsip_dialog *dlg,
286 const pjsip_evsub_user *user_cb,
287 pjsip_rx_data *rdata,
Benny Prijono26ff9062006-02-21 23:47:00 +0000288 unsigned option,
Benny Prijono834aee32006-02-19 01:38:06 +0000289 pjsip_evsub **p_evsub);
290
Benny Prijonod4e0abd2006-03-05 11:53:36 +0000291/**
292 * Forcefully destroy the subscription session. This function should only
293 * be called on special condition, such as when the subscription
294 * initialization has failed. For other conditions, application MUST terminate
295 * the subscription by sending the appropriate un(SUBSCRIBE) or NOTIFY.
296 *
297 * @param sub The event subscription.
298 * @param notify Specify whether the state notification callback
299 * should be called.
300 *
301 * @return PJ_SUCCESS if subscription session has been destroyed.
302 */
303PJ_DECL(pj_status_t) pjsip_evsub_terminate( pjsip_evsub *sub,
304 pj_bool_t notify );
305
Benny Prijono834aee32006-02-19 01:38:06 +0000306
307/**
308 * Get subscription state.
309 *
310 * @param sub Event subscription instance.
311 *
312 * @return Subscription state.
313 */
314PJ_DECL(pjsip_evsub_state) pjsip_evsub_get_state(pjsip_evsub *sub);
315
316
317/**
318 * Get the string representation of the subscription state.
319 *
320 * @param sub Event subscription instance.
321 *
322 * @return NULL terminated string.
323 */
324PJ_DECL(const char*) pjsip_evsub_get_state_name(pjsip_evsub *sub);
325
326
327/**
328 * Call this function to create request to initiate subscription, to
329 * refresh subcription, or to request subscription termination.
330 *
331 * @param sub Client subscription instance.
332 * @param method The method that establishes the subscription, such as
333 * SUBSCRIBE or REFER. If this argument is NULL, then
334 * SUBSCRIBE will be used.
335 * @param expires Subscription expiration. If the value is set to zero,
336 * this will request unsubscription. If the value is
337 * negative, default expiration as defined by the package
338 * will be used.
339 * @param p_tdata Pointer to receive the request.
340 *
341 * @return PJ_SUCCESS on success.
342 */
343PJ_DECL(pj_status_t) pjsip_evsub_initiate( pjsip_evsub *sub,
344 const pjsip_method *method,
345 pj_int32_t expires,
346 pjsip_tx_data **p_tdata);
347
348
349/**
350 * Accept the incoming subscription request by sending 2xx response to
351 * incoming SUBSCRIBE request.
352 *
353 * @param sub Server subscription instance.
354 * @param rdata The incoming subscription request message.
355 * @param st_code Status code, which MUST be final response.
356 * @param hdr_list Optional list of headers to be added in the response.
357 *
358 * @return PJ_SUCCESS on success.
359 */
360PJ_DECL(pj_status_t) pjsip_evsub_accept( pjsip_evsub *sub,
361 pjsip_rx_data *rdata,
362 int st_code,
363 const pjsip_hdr *hdr_list );
364
365
366/**
367 * For notifier, create NOTIFY request to subscriber, and set the state
368 * of the subscription.
369 *
370 * @param sub The server subscription (notifier) instance.
371 * @param state New state to set.
372 * @param state_str The state string name, if state contains value other
373 * than active, pending, or terminated. Otherwise this
374 * argument is ignored.
375 * @param reason Specify reason if new state is terminated, otherwise
376 * put NULL.
377 * @param p_tdata Pointer to receive request message.
378 *
379 * @return PJ_SUCCESS on success.
380 */
381PJ_DECL(pj_status_t) pjsip_evsub_notify( pjsip_evsub *sub,
382 pjsip_evsub_state state,
383 const pj_str_t *state_str,
384 const pj_str_t *reason,
385 pjsip_tx_data **p_tdata);
386
387
388/**
389 * For notifier, create a NOTIFY request that reflects current subscription
390 * status.
391 *
392 * @param sub The server subscription instance.
393 * @param p_tdata Pointer to receive the request messge.
394 *
395 * @return PJ_SUCCESS on success.
396 */
397PJ_DECL(pj_status_t) pjsip_evsub_current_notify( pjsip_evsub *sub,
398 pjsip_tx_data **p_tdata );
399
400
401
402/**
Benny Prijono26ff9062006-02-21 23:47:00 +0000403 * Send request message that was previously created with initiate(), notify(),
404 * or current_notify(). Application may also send request created with other
405 * functions, e.g. authentication. But the request MUST be either request
406 * that creates/refresh subscription or NOTIFY request.
Benny Prijono834aee32006-02-19 01:38:06 +0000407 *
408 * @param sub The event subscription object.
409 * @param tdata Request message to be send.
410 *
411 * @return PJ_SUCCESS on success.
412 */
413PJ_DECL(pj_status_t) pjsip_evsub_send_request( pjsip_evsub *sub,
414 pjsip_tx_data *tdata);
415
416
417
418/**
Benny Prijono8c715612006-02-25 02:04:42 +0000419 * Get the event subscription instance associated with the specified
420 * transaction.
Benny Prijono834aee32006-02-19 01:38:06 +0000421 *
422 * @param tsx The transaction.
423 *
424 * @return The event subscription instance registered in the
425 * transaction, if any.
426 */
427PJ_DECL(pjsip_evsub*) pjsip_tsx_get_evsub(pjsip_transaction *tsx);
428
429
430/**
431 * Set event subscription's module data.
432 *
433 * @param sub The event subscription.
Benny Prijono312aff92006-06-17 04:08:30 +0000434 * @param mod_id The module id.
Benny Prijono834aee32006-02-19 01:38:06 +0000435 * @param data Arbitrary data.
436 */
437PJ_DECL(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,
438 void *data );
439
440
441/**
442 * Get event subscription's module data.
443 *
444 * @param sub The event subscription.
445 * @param mod_id The module id.
446 *
447 * @return Data previously set at the specified id.
448 */
449PJ_DECL(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id );
450
451
452
453PJ_END_DECL
454
455/**
456 * @}
457 */
458
459#endif /* __PJSIP_SIMPLE_EVSUB_H__ */