2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2013, Digium, Inc.
6 * Mark Michelson <mmichelson@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
19 #ifndef _RES_PJSIP_PUBSUB_H
20 #define _RES_PJSIP_PUBSUB_H
22 #include "asterisk/linkedlists.h"
24 /* Forward declarations */
28 struct ast_sip_endpoint;
30 struct ast_datastore_info;
33 * \brief Opaque structure representing a publication
35 struct ast_sip_publication;
37 enum ast_sip_publish_state {
38 /*! Publication has just been initialized */
39 AST_SIP_PUBLISH_STATE_INITIALIZED,
40 /*! Publication is currently active */
41 AST_SIP_PUBLISH_STATE_ACTIVE,
42 /*! Publication has been terminated */
43 AST_SIP_PUBLISH_STATE_TERMINATED,
47 * \brief Callbacks that publication handlers will define
49 struct ast_sip_publish_handler {
50 /*! \brief The name of the event this handler deals with */
51 const char *event_name;
53 /*! \brief Publications */
54 struct ao2_container *publications;
57 * \brief Called when a PUBLISH to establish a new publication arrives.
59 * \param endpoint The endpoint from whom the PUBLISH arrived.
60 * \param resource The resource whose state is being published.
61 * \param event_configuration The name of the event type configuration to use for this resource.
62 * \return Response code for the incoming PUBLISH
64 int (*new_publication)(struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration);
66 * \brief Called when a publication has reached its expiration.
68 void (*publish_expire)(struct ast_sip_publication *pub);
70 * \brief Published resource has changed states.
72 * The state parameter can be used to take further action. For instance,
73 * if the state is AST_SIP_PUBLISH_STATE_INITIALIZED, then this is the initial
74 * PUBLISH request. This is a good time to set up datastores on the publication
75 * or any other initial needs.
77 * AST_SIP_PUBLISH_STATE_TERMINATED is used when the remote end is terminating
78 * its publication. This is a good opportunity to free any resources associated with
81 * AST_SIP_PUBLISH_STATE_ACTIVE is used when a publication that modifies state
84 * \param pub The publication whose state has changed
85 * \param body The body of the inbound PUBLISH
86 * \param state The state of the publication
88 int (*publication_state_change)(struct ast_sip_publication *pub, pjsip_msg_body *body,
89 enum ast_sip_publish_state state);
90 AST_LIST_ENTRY(ast_sip_publish_handler) next;
94 * \brief Given a publication, get the associated endpoint
96 * \param pub The publication
97 * \retval NULL Failure
98 * \retval non-NULL The associated endpoint
100 struct ast_sip_endpoint *ast_sip_publication_get_endpoint(struct ast_sip_publication *pub);
103 * \brief Given a publication, get the resource the publication is to
105 * \param pub The publication
106 * \return The resource
108 const char *ast_sip_publication_get_resource(const struct ast_sip_publication *pub);
111 * \brief Given a publication, get the configuration name for the event type in use
113 * \param pub The publication
114 * \return The configuration name
116 const char *ast_sip_publication_get_event_configuration(const struct ast_sip_publication *pub);
119 * \brief Register a publish handler
121 * \retval 0 Handler was registered successfully
122 * \retval non-zero Handler was not registered successfully
124 int ast_sip_register_publish_handler(struct ast_sip_publish_handler *handler);
127 * \brief Unregister a publish handler
129 void ast_sip_unregister_publish_handler(struct ast_sip_publish_handler *handler);
132 * \brief Add a datastore to a SIP publication
134 * Note that SIP uses reference counted datastores. The datastore passed into this function
135 * must have been allocated using ao2_alloc() or there will be serious problems.
137 * \param publication The publication to add the datastore to
138 * \param datastore The datastore to be added to the subscription
142 int ast_sip_publication_add_datastore(struct ast_sip_publication *publication, struct ast_datastore *datastore);
145 * \brief Retrieve a publication datastore
147 * The datastore retrieved will have its reference count incremented. When the caller is done
148 * with the datastore, the reference counted needs to be decremented using ao2_ref().
150 * \param publication The publication from which to retrieve the datastore
151 * \param name The name of the datastore to retrieve
152 * \retval NULL Failed to find the specified datastore
153 * \retval non-NULL The specified datastore
155 struct ast_datastore *ast_sip_publication_get_datastore(struct ast_sip_publication *publication, const char *name);
158 * \brief Remove a publication datastore from the publication
160 * This operation may cause the datastore's free() callback to be called if the reference
161 * count reaches zero.
163 * \param publication The publication to remove the datastore from
164 * \param name The name of the datastore to remove
166 void ast_sip_publication_remove_datastore(struct ast_sip_publication *publication, const char *name);
169 * \brief Opaque structure representing an RFC 3265 SIP subscription
171 struct ast_sip_subscription;
174 * \brief Role for the subscription that is being created
176 enum ast_sip_subscription_role {
177 /* Sending SUBSCRIBEs, receiving NOTIFYs */
179 /* Sending NOTIFYs, receiving SUBSCRIBEs */
184 * \brief Data for responses to SUBSCRIBEs and NOTIFIEs
186 * Some of PJSIP's evsub callbacks expect us to provide them
187 * with data so that they can craft a response rather than have
188 * us create our own response.
190 * Filling in the structure is optional, since the framework
191 * will automatically respond with a 200 OK response if we do
192 * not provide it with any additional data.
194 struct ast_sip_subscription_response_data {
195 /*! Status code of the response */
197 /*! Optional status text */
198 const char *status_text;
199 /*! Optional additional headers to add to the response */
200 struct ast_variable *headers;
201 /*! Optional body to add to the response */
202 struct ast_sip_body *body;
205 #define AST_SIP_MAX_ACCEPT 32
206 enum ast_sip_subscription_notify_reason {
207 /*! Initial NOTIFY for subscription */
208 AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED,
209 /*! Subscription has been renewed */
210 AST_SIP_SUBSCRIPTION_NOTIFY_REASON_RENEWED,
211 /*! Subscription is being terminated */
212 AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED,
213 /*! Other unspecified reason */
214 AST_SIP_SUBSCRIPTION_NOTIFY_REASON_OTHER
217 struct ast_sip_notifier {
219 * \brief Default body type defined for the event package this notifier handles.
221 * Typically, a SUBSCRIBE request will contain one or more Accept headers that tell
222 * what format they expect the body of NOTIFY requests to use. However, every event
223 * package is required to define a default body format type to be used if a SUBSCRIBE
224 * request for the event contains no Accept header.
226 const char *default_accept;
228 * \brief Called when a SUBSCRIBE arrives attempting to establish a new subscription.
230 * The notifier is expected to return the response that should be sent to the
233 * If a 200-class response is returned, then the notifier's notify_required
234 * callback will immediately be called into with a reason of
235 * AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED.
237 * \param endpoint The endpoint from which we received the SUBSCRIBE
238 * \param resource The name of the resource to which the subscription is being made
239 * \return The response code to send to the SUBSCRIBE.
241 int (*new_subscribe)(struct ast_sip_endpoint *endpoint, const char *resource);
243 * \brief The subscription is in need of a NOTIFY request.
245 * A reason of AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED is given immediately
246 * after a SUBSCRIBE is accepted. This is a good opportunity for the notifier to
247 * perform setup duties such as establishing Stasis subscriptions or adding
248 * datastores to the subscription.
250 * A reason of AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED is given when the
251 * subscriber has terminated the subscription. If there are any duties that the
254 * \param sub The subscription to send the NOTIFY on.
255 * \param reason The reason why the NOTIFY is being sent.
259 int (*notify_required)(struct ast_sip_subscription *sub, enum ast_sip_subscription_notify_reason reason);
262 struct ast_sip_subscriber {
264 * \brief A NOTIFY has been received.
266 * The body of the NOTIFY is provided so that it may be parsed and appropriate
267 * internal state change may be generated.
269 * The state can be used to determine if the subscription has been terminated
270 * by the far end or if this is just a typical resource state change.
272 * \param sub The subscription on which the NOTIFY arrived
273 * \param body The body of the NOTIFY
274 * \param state The subscription state
276 void (*state_change)(struct ast_sip_subscription *sub, pjsip_msg_body *body, enum pjsip_evsub_state state);
279 struct ast_sip_subscription_handler {
280 /*! The name of the event this subscriber deals with */
281 const char *event_name;
282 /*! The types of body this subscriber accepts. */
283 const char *accept[AST_SIP_MAX_ACCEPT];
285 * \brief Called when a subscription is to be destroyed
287 * The handler is not expected to send any sort of requests or responses
288 * during this callback. The handler MUST, however, begin the destruction
289 * process for the subscription during this callback.
291 void (*subscription_shutdown)(struct ast_sip_subscription *subscription);
293 * \brief Converts the subscriber to AMI
295 * \param sub The subscription
296 * \param buf The string to write AMI data
298 void (*to_ami)(struct ast_sip_subscription *sub, struct ast_str **buf);
299 /*! Subscriber callbacks for this handler */
300 struct ast_sip_subscriber *subscriber;
301 /*! Notifier callbacks for this handler */
302 struct ast_sip_notifier *notifier;
303 AST_LIST_ENTRY(ast_sip_subscription_handler) next;
307 * \brief Create a new ast_sip_subscription structure
309 * When a subscriber wishes to create a subscription, it may call this function
310 * to allocate resources and to send the initial SUBSCRIBE out.
312 * \param subscriber The subscriber that is making the request.
313 * \param endpoint The endpoint to whome the SUBSCRIBE will be sent.
314 * \param resource The resource to place in the SUBSCRIBE's Request-URI.
316 struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
317 struct ast_sip_endpoint *endpoint, const char *resource);
321 * \brief Get the endpoint that is associated with this subscription
323 * This function will increase the reference count of the endpoint. Be sure to
324 * release the reference to it when you are finished with the endpoint.
326 * \retval NULL Could not get endpoint
327 * \retval non-NULL The endpoint
329 struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub);
332 * \brief Get the serializer for the subscription
334 * Tasks that originate outside of a SIP servant thread should get the serializer
335 * and push the task to the serializer.
337 * \param sub The subscription
338 * \retval NULL Failure
339 * \retval non-NULL The subscription's serializer
341 struct ast_taskprocessor *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub);
344 * \brief Notify a SIP subscription of a state change.
346 * This will create a NOTIFY body to be sent out for the subscribed resource.
347 * On real subscriptions, a NOTIFY request will be generated and sent.
348 * On virtual subscriptions, the NOTIFY is saved on the virtual subscription and the
349 * parent subscription is alerted.
351 * \param sub The subscription on which a state change is occurring.
352 * \param notify_data Event package-specific data used to create the NOTIFY body.
353 * \param terminate True if this NOTIFY is intended to terminate the subscription.
355 * \retval non-zero Failure
357 int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_data, int terminate);
360 * \brief Retrieve the local URI for this subscription
362 * This is the local URI as determined by the underlying SIP dialog.
364 * \param sub The subscription
365 * \param[out] buf The buffer into which to store the URI.
366 * \param size The size of the buffer.
368 void ast_sip_subscription_get_local_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
371 * \brief Retrive the remote URI for this subscription
373 * This is the remote URI as determined by the underlying SIP dialog.
375 * \param sub The subscription
376 * \param[out] buf The buffer into which to store the URI.
377 * \param size The size of the buffer.
379 void ast_sip_subscription_get_remote_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
382 * \brief Get the name of the subscribed resource.
384 const char *ast_sip_subscription_get_resource_name(struct ast_sip_subscription *sub);
387 * \brief Get a header value for a subscription.
389 * For notifiers, the headers of the inbound SUBSCRIBE that started the dialog
390 * are stored on the subscription. This method allows access to the header. The
391 * return is the same as pjsip_msg_find_hdr_by_name(), meaning that it is dependent
392 * on the header being searched for.
394 * \param sub The subscription to search in.
395 * \param header The name of the header to search for.
396 * \return The discovered header, or NULL if the header cannot be found.
398 void *ast_sip_subscription_get_header(const struct ast_sip_subscription *sub, const char *header);
401 * \brief Send a request created via a PJSIP evsub method
403 * Callers of this function should take care to do so within a SIP servant
406 * \param sub The subscription on which to send the request
407 * \param tdata The request to send
409 * \retval non-zero Failure
411 int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata);
414 * \brief Alternative for ast_datastore_alloc()
416 * There are two major differences between this and ast_datastore_alloc()
417 * 1) This allocates a refcounted object
418 * 2) This will fill in a uid if one is not provided
420 * DO NOT call ast_datastore_free() on a datastore allocated in this
421 * way since that function will attempt to free the datastore rather
422 * than play nicely with its refcount.
424 * \param info Callbacks for datastore
425 * \param uid Identifier for datastore
426 * \retval NULL Failed to allocate datastore
427 * \retval non-NULL Newly allocated datastore
429 struct ast_datastore *ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid);
432 * \brief Add a datastore to a SIP subscription
434 * Note that SIP uses reference counted datastores. The datastore passed into this function
435 * must have been allocated using ao2_alloc() or there will be serious problems.
437 * \param subscription The ssubscription to add the datastore to
438 * \param datastore The datastore to be added to the subscription
442 int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore);
445 * \brief Retrieve a subscription datastore
447 * The datastore retrieved will have its reference count incremented. When the caller is done
448 * with the datastore, the reference counted needs to be decremented using ao2_ref().
450 * \param subscription The subscription from which to retrieve the datastore
451 * \param name The name of the datastore to retrieve
452 * \retval NULL Failed to find the specified datastore
453 * \retval non-NULL The specified datastore
455 struct ast_datastore *ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name);
458 * \brief Remove a subscription datastore from the subscription
460 * This operation may cause the datastore's free() callback to be called if the reference
461 * count reaches zero.
463 * \param subscription The subscription to remove the datastore from
464 * \param name The name of the datastore to remove
466 void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name);
469 * \brief Register a subscription handler
471 * \retval 0 Handler was registered successfully
472 * \retval non-zero Handler was not registered successfully
474 int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler);
477 * \brief Unregister a subscription handler
479 void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler);
482 * \brief Pubsub body generator
484 * A body generator is responsible for taking Asterisk content
485 * and converting it into a body format to be placed in an outbound
486 * SIP NOTIFY or PUBLISH request.
488 struct ast_sip_pubsub_body_generator {
490 * \brief Content type
491 * In "plain/text", "plain" is the type
495 * \brief Content subtype
496 * In "plain/text", "text" is the subtype
500 * \brief allocate body structure.
502 * Body generators will have this method called when a NOTIFY
503 * or PUBLISH body needs to be created. The type returned depends on
504 * the type of content being produced for the body. The data parameter
505 * is provided by the subscription handler and will vary between different
508 * \param data The subscription data provided by the event handler
509 * \retval non-NULL The allocated body
510 * \retval NULL Failure
512 void *(*allocate_body)(void *data);
514 * \brief Add content to the body of a SIP request
516 * The body of the request has already been allocated by the body generator's
517 * allocate_body callback.
519 * \param body The body of the SIP request. The type is determined by the
521 * \param data The subscription data used to populate the body. The type is
522 * determined by the content type.
524 int (*generate_body_content)(void *body, void *data);
526 * \brief Convert the body to a string.
528 * \param body The request body.
529 * \param str The converted string form of the request body
531 void (*to_string)(void *body, struct ast_str **str);
533 * \brief Deallocate resources created for the body
535 * Optional callback to destroy resources allocated for the
538 * \param body Body to be destroyed
540 void (*destroy_body)(void *body);
541 AST_LIST_ENTRY(ast_sip_pubsub_body_generator) list;
545 * \brief Body supplement
547 * Body supplements provide additions to bodies not already
548 * provided by body generators. This may include proprietary
549 * extensions, optional content, or other nonstandard fare.
551 struct ast_sip_pubsub_body_supplement {
553 * \brief Content type
554 * In "plain/text", "plain" is the type
558 * \brief Content subtype
559 * In "plain/text", "text" is the subtype
563 * \brief Add additional content to a SIP request body.
565 * A body generator will have already allocated a body and populated
566 * it with base data for the event. The supplement's duty is, if desired,
567 * to extend the body to have optional data beyond what a base RFC specifies.
569 * \param body The body of the SIP request. The type is determined by the
570 * body generator that allocated the body.
571 * \param data The subscription data used to populate the body. The type is
572 * determined by the content type.
574 int (*supplement_body)(void *body, void *data);
575 AST_LIST_ENTRY(ast_sip_pubsub_body_supplement) list;
580 * \brief Generate body content for a PUBLISH or NOTIFY
582 * This function takes a pre-allocated body and calls into registered body
583 * generators in order to fill in the body with appropriate details.
584 * The primary body generator will be called first, followed by the
585 * supplementary body generators
587 * \param content_type The content type of the body
588 * \param content_subtype The content subtype of the body
589 * \param data The data associated with body generation.
590 * \param[out] str The string representation of the generated body
592 * \retval non-zero Failure
594 int ast_sip_pubsub_generate_body_content(const char *content_type,
595 const char *content_subtype, void *data, struct ast_str **str);
599 * \brief Register a body generator with the pubsub core.
601 * This may fail if an attempt is made to register a primary body supplement
602 * for a given content type if a primary body supplement for that content type
603 * has already been registered.
605 * \param generator Body generator to register
609 int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator *generator);
613 * \brief Unregister a body generator with the pubsub core.
615 * \param generator Body generator to unregister
617 void ast_sip_pubsub_unregister_body_generator(struct ast_sip_pubsub_body_generator *generator);
621 * \brief Register a body generator with the pubsub core.
623 * This may fail if an attempt is made to register a primary body supplement
624 * for a given content type if a primary body supplement for that content type
625 * has already been registered.
627 * \param generator Body generator to register
631 int ast_sip_pubsub_register_body_supplement(struct ast_sip_pubsub_body_supplement *supplement);
635 * \brief Unregister a body generator with the pubsub core.
637 * \param generator Body generator to unregister
639 void ast_sip_pubsub_unregister_body_supplement(struct ast_sip_pubsub_body_supplement *supplement);
643 * \brief Get the body type used for this subscription
645 const char *ast_sip_subscription_get_body_type(struct ast_sip_subscription *sub);
649 * \brief Get the body subtype used for this subscription
651 const char *ast_sip_subscription_get_body_subtype(struct ast_sip_subscription *sub);
653 #endif /* RES_PJSIP_PUBSUB_H */