Asterisk - The Open Source Telephony Project  21.4.1
res_pjsip_pubsub.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Mark Michelson <mmichelson@digium.com>
7  *
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.
13  *
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.
17  */
18 
19 #ifndef _RES_PJSIP_PUBSUB_H
20 #define _RES_PJSIP_PUBSUB_H
21 
22 #include "asterisk/linkedlists.h"
23 
24 /* Forward declarations */
25 struct pjsip_rx_data;
26 struct pjsip_tx_data;
27 struct pjsip_evsub;
28 struct ast_sip_endpoint;
29 struct ast_datastore;
30 struct ast_datastore_info;
31 
32 /*!
33  * \brief Opaque structure representing a publication
34  */
35 struct ast_sip_publication;
36 
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,
44 };
45 
46 /*!
47  * \brief Callbacks that publication handlers will define
48  */
50  /*! \brief The name of the event this handler deals with */
51  const char *event_name;
52 
53  /*! \brief Publications */
55 
56  /*!
57  * \brief Called when a PUBLISH to establish a new publication arrives.
58  *
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
63  */
64  int (*new_publication)(struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration);
65  /*!
66  * \brief Called when a publication has reached its expiration.
67  */
68  void (*publish_expire)(struct ast_sip_publication *pub);
69  /*!
70  * \brief Published resource has changed states.
71  *
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.
76  *
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
79  * the publication.
80  *
81  * AST_SIP_PUBLISH_STATE_ACTIVE is used when a publication that modifies state
82  * arrives.
83  *
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
87  */
88  int (*publication_state_change)(struct ast_sip_publication *pub, pjsip_msg_body *body,
89  enum ast_sip_publish_state state);
91 };
92 
93 /*!
94  * \brief Given a publication, get the associated endpoint
95  *
96  * \param pub The publication
97  * \retval NULL Failure
98  * \retval non-NULL The associated endpoint
99  */
100 struct ast_sip_endpoint *ast_sip_publication_get_endpoint(struct ast_sip_publication *pub);
101 
102 /*!
103  * \brief Given a publication, get the resource the publication is to
104  *
105  * \param pub The publication
106  * \return The resource
107  */
108 const char *ast_sip_publication_get_resource(const struct ast_sip_publication *pub);
109 
110 /*!
111  * \brief Given a publication, get the configuration name for the event type in use
112  *
113  * \param pub The publication
114  * \return The configuration name
115  */
116 const char *ast_sip_publication_get_event_configuration(const struct ast_sip_publication *pub);
117 
118 /*!
119  * \brief Register a publish handler
120  *
121  * \retval 0 Handler was registered successfully
122  * \retval non-zero Handler was not registered successfully
123  */
124 int ast_sip_register_publish_handler(struct ast_sip_publish_handler *handler);
125 
126 /*!
127  * \brief Unregister a publish handler
128  */
129 void ast_sip_unregister_publish_handler(struct ast_sip_publish_handler *handler);
130 
131 /*!
132  * \brief Add a datastore to a SIP publication
133  *
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.
136  *
137  * \param publication The publication to add the datastore to
138  * \param datastore The datastore to be added to the subscription
139  * \retval 0 Success
140  * \retval -1 Failure
141  */
142 int ast_sip_publication_add_datastore(struct ast_sip_publication *publication, struct ast_datastore *datastore);
143 
144 /*!
145  * \brief Retrieve a publication datastore
146  *
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().
149  *
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
154  */
155 struct ast_datastore *ast_sip_publication_get_datastore(struct ast_sip_publication *publication, const char *name);
156 
157 /*!
158  * \brief Remove a publication datastore from the publication
159  *
160  * This operation may cause the datastore's free() callback to be called if the reference
161  * count reaches zero.
162  *
163  * \param publication The publication to remove the datastore from
164  * \param name The name of the datastore to remove
165  */
166 void ast_sip_publication_remove_datastore(struct ast_sip_publication *publication, const char *name);
167 
168 /*!
169  * \brief Get the datastores container for a publication
170  *
171  * \param publication The publication to get the datastores container from
172  *
173  * \retval NULL datastores container not present
174  * \retval non-NULL datastores container
175  *
176  * \note The container is NOT returned with reference count bumped
177  *
178  * \since 14.0.0
179  */
180 struct ao2_container *ast_sip_publication_get_datastores(const struct ast_sip_publication *publication);
181 
182 /*!
183  * \brief Opaque structure representing an RFC 3265 SIP subscription
184  */
185 struct ast_sip_subscription;
186 
187 /*!
188  * \brief Role for the subscription that is being created
189  */
190 enum ast_sip_subscription_role {
191  /* Sending SUBSCRIBEs, receiving NOTIFYs */
192  AST_SIP_SUBSCRIBER,
193  /* Sending NOTIFYs, receiving SUBSCRIBEs */
194  AST_SIP_NOTIFIER,
195 };
196 
197 /*!
198  * \brief Data for responses to SUBSCRIBEs and NOTIFIEs
199  *
200  * Some of PJSIP's evsub callbacks expect us to provide them
201  * with data so that they can craft a response rather than have
202  * us create our own response.
203  *
204  * Filling in the structure is optional, since the framework
205  * will automatically respond with a 200 OK response if we do
206  * not provide it with any additional data.
207  */
209  /*! Status code of the response */
211  /*! Optional status text */
212  const char *status_text;
213  /*! Optional additional headers to add to the response */
215  /*! Optional body to add to the response */
217 };
218 
219 #define AST_SIP_MAX_ACCEPT 32
220 enum ast_sip_subscription_notify_reason {
221  /*! Initial NOTIFY for subscription */
222  AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED,
223  /*! Subscription has been renewed */
224  AST_SIP_SUBSCRIPTION_NOTIFY_REASON_RENEWED,
225  /*! Subscription is being terminated */
226  AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED,
227  /*! Other unspecified reason */
228  AST_SIP_SUBSCRIPTION_NOTIFY_REASON_OTHER
229 };
230 
231 /*! Type used for extension state/presence */
232 #define AST_SIP_EXTEN_STATE_DATA "ast_sip_exten_state_data"
233 /*! Type used for conveying mailbox state */
234 #define AST_SIP_MESSAGE_ACCUMULATOR "ast_sip_message_accumulator"
235 /*! Type used for device feature synchronization */
236 #define AST_SIP_DEVICE_FEATURE_SYNC_DATA "ast_sip_device_feature_sync_data"
237 
238 /*!
239  * \brief Data used to create bodies for NOTIFY/PUBLISH requests.
240  */
242  /*! The type of the data */
243  const char *body_type;
244  /*! The actual data from which the body is generated */
245  void *body_data;
246 };
247 
249  /*!
250  * \brief Default body type defined for the event package this notifier handles.
251  *
252  * Typically, a SUBSCRIBE request will contain one or more Accept headers that tell
253  * what format they expect the body of NOTIFY requests to use. However, every event
254  * package is required to define a default body format type to be used if a SUBSCRIBE
255  * request for the event contains no Accept header.
256  */
257  const char *default_accept;
258  /*!
259  * \brief Called when a SUBSCRIBE arrives attempting to establish a new subscription.
260  *
261  * The notifier is expected to return the response that should be sent to the
262  * SUBSCRIBE request.
263  *
264  * If a 200-class response is returned, then the notifier's notify_required
265  * callback will immediately be called into with a reason of
266  * AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED.
267  *
268  * \param endpoint The endpoint from which we received the SUBSCRIBE
269  * \param resource The name of the resource to which the subscription is being made
270  * \return The response code to send to the SUBSCRIBE.
271  */
272  int (*new_subscribe)(struct ast_sip_endpoint *endpoint, const char *resource);
273  /*!
274  * \brief Same as new_subscribe, but also pass a handle to the pjsip_rx_data
275  *
276  * \note If this callback exists, it will be executed, otherwise new_subscribe will be.
277  * Only use this if you need the rdata. Otherwise, use new_subscribe.
278  *
279  * \param endpoint The endpoint from which we received the SUBSCRIBE
280  * \param resource The name of the resource to which the subscription is being made
281  * \param rdata The pjsip_rx_data for incoming subscription
282  * \return The response code to send to the SUBSCRIBE.
283  */
284  int (*new_subscribe_with_rdata)(struct ast_sip_endpoint *endpoint, const char *resource, pjsip_rx_data *rdata);
285  /*!
286  * \brief Called when an inbound subscription has been accepted.
287  *
288  * This is a prime opportunity for notifiers to add any notifier-specific
289  * data to the subscription (such as datastores) that it needs to.
290  *
291  * \note There is no need to send a NOTIFY request when this callback
292  * is called
293  *
294  * \param sub The new subscription
295  * \retval 0 Success
296  * \retval -1 Failure
297  */
298  int (*subscription_established)(struct ast_sip_subscription *sub);
299  /*!
300  * \brief Called when a SUBSCRIBE arrives for an already active subscription.
301  *
302  * \param sub The existing subscription
303  * \retval 0 Success
304  * \retval -1 Failure
305  */
306  int (*refresh_subscribe)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
307  /*!
308  * \brief Optional callback to execute before sending outgoing NOTIFY requests.
309  * Because res_pjsip_pubsub creates the tdata internally, this allows modules
310  * to access the tdata if needed, e.g. to add custom headers.
311  *
312  * \param sub The existing subscription
313  * \param tdata The pjsip_tx_data to use for the outgoing NOTIFY
314  * \retval 0 Success
315  * \retval -1 Failure
316  */
317  int (*notify_created)(struct ast_sip_subscription *sub, pjsip_tx_data *tdata);
318  /*!
319  * \brief Supply data needed to create a NOTIFY body.
320  *
321  * The returned data must be an ao2 object. The caller of this function
322  * will be responsible for decrementing the refcount of the returned object
323  *
324  * \param sub The subscription
325  * \return An ao2 object that can be used to create a NOTIFY body.
326  */
327  void *(*get_notify_data)(struct ast_sip_subscription *sub);
328  /*!
329  * \brief Supply Display Name for resource
330  *
331  * \param endpoint The endpoint from which we received the SUBSCRIBE
332  * \param resource The name of the resource to which the subscription is being made
333  * \param display_name buffer for Display Name
334  * \param display_name_size size of display_name buffer
335  * \retval 0 Success
336  * \retval -1 Failure
337  */
338  int (*get_resource_display_name)(struct ast_sip_endpoint *endpoint, const char *resource, char *display_name, int display_name_size);
339 };
340 
342  /*!
343  * \brief A NOTIFY has been received.
344  *
345  * The body of the NOTIFY is provided so that it may be parsed and appropriate
346  * internal state change may be generated.
347  *
348  * The state can be used to determine if the subscription has been terminated
349  * by the far end or if this is just a typical resource state change.
350  *
351  * \param sub The subscription on which the NOTIFY arrived
352  * \param body The body of the NOTIFY
353  * \param state The subscription state
354  */
355  void (*state_change)(struct ast_sip_subscription *sub, pjsip_msg_body *body, enum pjsip_evsub_state state);
356 };
357 
359  /*! The name of the event this subscriber deals with */
360  const char *event_name;
361  /*! Type of data used to generate NOTIFY bodies */
362  const char *body_type;
363  /*! The types of body this subscriber accepts. */
364  const char *accept[AST_SIP_MAX_ACCEPT];
365  /*!
366  * \brief Called when a subscription is to be destroyed
367  *
368  * The handler is not expected to send any sort of requests or responses
369  * during this callback. The handler MUST, however, begin the destruction
370  * process for the subscription during this callback.
371  */
372  void (*subscription_shutdown)(struct ast_sip_subscription *subscription);
373  /*!
374  * \brief Converts the subscriber to AMI
375  *
376  * \param sub The subscription
377  * \param buf The string to write AMI data
378  */
379  void (*to_ami)(struct ast_sip_subscription *sub, struct ast_str **buf);
380  /*! Subscriber callbacks for this handler */
382  /*! Notifier callbacks for this handler */
385 };
386 
387 /*!
388  * \brief Create a new ast_sip_subscription structure
389  *
390  * When a subscriber wishes to create a subscription, it may call this function
391  * to allocate resources and to send the initial SUBSCRIBE out.
392  *
393  * \param handler The subscriber that is making the request.
394  * \param endpoint The endpoint to whome the SUBSCRIBE will be sent.
395  * \param resource The resource to place in the SUBSCRIBE's Request-URI.
396  */
397 struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
398  struct ast_sip_endpoint *endpoint, const char *resource);
399 
400 /*!
401  * \brief Get the pjsip dialog that is associated with this subscription
402  * \since 13.9.0
403  *
404  * \retval NULL Could not get dialog
405  * \retval non-NULL The dialog
406  */
407 pjsip_dialog *ast_sip_subscription_get_dialog(struct ast_sip_subscription *sub);
408 
409 /*!
410  * \brief Get the endpoint that is associated with this subscription
411  *
412  * This function will increase the reference count of the endpoint. Be sure to
413  * release the reference to it when you are finished with the endpoint.
414  *
415  * \retval NULL Could not get endpoint
416  * \retval non-NULL The endpoint
417  */
418 struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub);
419 
420 /*!
421  * \brief Get the serializer for the subscription
422  *
423  * Tasks that originate outside of a SIP servant thread should get the serializer
424  * and push the task to the serializer.
425  *
426  * \param sub The subscription
427  * \retval NULL Failure
428  * \retval non-NULL The subscription's serializer
429  */
430 struct ast_taskprocessor *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub);
431 
432 /*!
433  * \brief Notify a SIP subscription of a state change.
434  *
435  * This tells the pubsub core that the state of a subscribed resource has changed.
436  * The pubsub core will generate an appropriate NOTIFY request to send to the
437  * subscriber.
438  *
439  * \param sub The subscription on which a state change is occurring.
440  * \param notify_data Event package-specific data used to create the NOTIFY body.
441  * \param terminate True if this NOTIFY is intended to terminate the subscription.
442  * \retval 0 Success
443  * \retval non-zero Failure
444  */
445 int ast_sip_subscription_notify(struct ast_sip_subscription *sub, struct ast_sip_body_data *notify_data, int terminate);
446 
447 /*!
448  * \brief Retrieve the local sip uri for this subscription
449  * \since 13.9.0
450  *
451  * This is the local sip URI of the subscribed resource.
452  *
453  * \param sub The subscription
454  * \retval NULL Could not get uri
455  * \retval non-NULL The local pjsip_sip_uri
456  */
457 pjsip_sip_uri *ast_sip_subscription_get_sip_uri(struct ast_sip_subscription *sub);
458 
459 /*!
460  * \brief Retrieve the local URI for this subscription
461  *
462  * This is the local URI of the subscribed resource.
463  *
464  * \param sub The subscription
465  * \param[out] buf The buffer into which to store the URI.
466  * \param size The size of the buffer.
467  */
468 void ast_sip_subscription_get_local_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
469 
470 /*!
471  * \brief Retrive the remote URI for this subscription
472  *
473  * This is the remote URI as determined by the underlying SIP dialog.
474  *
475  * \param sub The subscription
476  * \param[out] buf The buffer into which to store the URI.
477  * \param size The size of the buffer.
478  */
479 void ast_sip_subscription_get_remote_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
480 
481 /*!
482  * \brief Get the name of the subscribed resource.
483  */
484 const char *ast_sip_subscription_get_resource_name(struct ast_sip_subscription *sub);
485 
486 /*!
487  * \brief Get whether the subscription has been terminated or not.
488  *
489  * \param sub The subscription.
490  * \retval 0 not terminated.
491  * \retval 1 terminated.
492  * \since 13.4.0
493  */
494 int ast_sip_subscription_is_terminated(const struct ast_sip_subscription *sub);
495 
496 /*!
497  * \brief Get a header value for a subscription.
498  *
499  * For notifiers, the headers of the inbound SUBSCRIBE that started the dialog
500  * are stored on the subscription. This method allows access to the header. The
501  * return is the same as pjsip_msg_find_hdr_by_name(), meaning that it is dependent
502  * on the header being searched for.
503  *
504  * \param sub The subscription to search in.
505  * \param header The name of the header to search for.
506  * \return The discovered header, or NULL if the header cannot be found.
507  */
508 void *ast_sip_subscription_get_header(const struct ast_sip_subscription *sub, const char *header);
509 
510 /*!
511  * \brief Send a request created via a PJSIP evsub method
512  *
513  * Callers of this function should take care to do so within a SIP servant
514  * thread.
515  *
516  * \param sub The subscription on which to send the request
517  * \param tdata The request to send
518  * \retval 0 Success
519  * \retval non-zero Failure
520  */
521 int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata);
522 
523 /*!
524  * \brief Alternative for ast_datastore_alloc()
525  *
526  * There are two major differences between this and ast_datastore_alloc()
527  * 1) This allocates a refcounted object
528  * 2) This will fill in a uid if one is not provided
529  *
530  * DO NOT call ast_datastore_free() on a datastore allocated in this
531  * way since that function will attempt to free the datastore rather
532  * than play nicely with its refcount.
533  *
534  * \param info Callbacks for datastore
535  * \param uid Identifier for datastore
536  * \retval NULL Failed to allocate datastore
537  * \retval non-NULL Newly allocated datastore
538  */
539 struct ast_datastore *ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid);
540 
541 /*!
542  * \brief Add a datastore to a SIP subscription
543  *
544  * Note that SIP uses reference counted datastores. The datastore passed into this function
545  * must have been allocated using ao2_alloc() or there will be serious problems.
546  *
547  * \param subscription The ssubscription to add the datastore to
548  * \param datastore The datastore to be added to the subscription
549  * \retval 0 Success
550  * \retval -1 Failure
551  */
552 int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore);
553 
554 /*!
555  * \brief Retrieve a subscription datastore
556  *
557  * The datastore retrieved will have its reference count incremented. When the caller is done
558  * with the datastore, the reference counted needs to be decremented using ao2_ref().
559  *
560  * \param subscription The subscription from which to retrieve the datastore
561  * \param name The name of the datastore to retrieve
562  * \retval NULL Failed to find the specified datastore
563  * \retval non-NULL The specified datastore
564  */
565 struct ast_datastore *ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name);
566 
567 /*!
568  * \brief Remove a subscription datastore from the subscription
569  *
570  * This operation may cause the datastore's free() callback to be called if the reference
571  * count reaches zero.
572  *
573  * \param subscription The subscription to remove the datastore from
574  * \param name The name of the datastore to remove
575  */
576 void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name);
577 
578 /*!
579  * \brief Get the datastores container for a subscription
580  *
581  * \param subscription The subscription to get the datastores container from
582  *
583  * \retval NULL datastores container not present
584  * \retval non-NULL datastores container
585  *
586  * \note The container is NOT returned with reference count bumped
587  *
588  * \since 14.0.0
589  */
590 struct ao2_container *ast_sip_subscription_get_datastores(const struct ast_sip_subscription *subscription);
591 
592 /*!
593  * \since 13.31.0
594  * \since 16.8.0
595  * \since 17.2.0
596  * \brief Set persistence data for a subscription
597  *
598  * \param subscription The subscription to set persistence data on
599  * \param persistence_data The persistence data to set
600  *
601  * \note This steals the reference to persistence_data
602  */
603 void ast_sip_subscription_set_persistence_data(struct ast_sip_subscription *subscription, struct ast_json *persistence_data);
604 
605 /*!
606  * \since 13.31.0
607  * \since 16.8.0
608  * \since 17.2.0
609  * \brief Retrieve persistence data for a subscription
610  *
611  * \param subscription The subscription to retrieve persistence data from
612  */
613 const struct ast_json *ast_sip_subscription_get_persistence_data(const struct ast_sip_subscription *subscription);
614 
615 /*!
616  * \brief Register a subscription handler
617  *
618  * \retval 0 Handler was registered successfully
619  * \retval non-zero Handler was not registered successfully
620  */
621 int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler);
622 
623 /*!
624  * \brief Unregister a subscription handler
625  */
626 void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler);
627 
628 /*!
629  * \brief Pubsub body generator
630  *
631  * A body generator is responsible for taking Asterisk content
632  * and converting it into a body format to be placed in an outbound
633  * SIP NOTIFY or PUBLISH request.
634  */
636  /*!
637  * \brief Content type
638  * In "plain/text", "plain" is the type
639  */
640  const char *type;
641  /*!
642  * \brief Content subtype
643  * In "plain/text", "text" is the subtype
644  */
645  const char *subtype;
646  /*! Type of data the body generator takes as input */
647  const char *body_type;
648  /*!
649  * \brief allocate body structure.
650  *
651  * Body generators will have this method called when a NOTIFY
652  * or PUBLISH body needs to be created. The type returned depends on
653  * the type of content being produced for the body. The data parameter
654  * is provided by the subscription handler and will vary between different
655  * event types.
656  *
657  * \param data The subscription data provided by the event handler
658  * \retval non-NULL The allocated body
659  * \retval NULL Failure
660  */
661  void *(*allocate_body)(void *data);
662  /*!
663  * \brief Add content to the body of a SIP request
664  *
665  * The body of the request has already been allocated by the body generator's
666  * allocate_body callback.
667  *
668  * \param body The body of the SIP request. The type is determined by the
669  * content type.
670  * \param data The subscription data used to populate the body. The type is
671  * determined by the content type.
672  */
673  int (*generate_body_content)(void *body, void *data);
674  /*!
675  * \brief Convert the body to a string.
676  *
677  * \param body The request body.
678  * \param str The converted string form of the request body
679  */
680  void (*to_string)(void *body, struct ast_str **str);
681  /*!
682  * \brief Deallocate resources created for the body
683  *
684  * Optional callback to destroy resources allocated for the
685  * message body.
686  *
687  * \param body Body to be destroyed
688  */
689  void (*destroy_body)(void *body);
690  AST_LIST_ENTRY(ast_sip_pubsub_body_generator) list;
691 };
692 
693 /*!
694  * \brief Body supplement
695  *
696  * Body supplements provide additions to bodies not already
697  * provided by body generators. This may include proprietary
698  * extensions, optional content, or other nonstandard fare.
699  */
701  /*!
702  * \brief Content type
703  * In "plain/text", "plain" is the type
704  */
705  const char *type;
706  /*!
707  * \brief Content subtype
708  * In "plain/text", "text" is the subtype
709  */
710  const char *subtype;
711  /*!
712  * \brief Add additional content to a SIP request body.
713  *
714  * A body generator will have already allocated a body and populated
715  * it with base data for the event. The supplement's duty is, if desired,
716  * to extend the body to have optional data beyond what a base RFC specifies.
717  *
718  * \param body The body of the SIP request. The type is determined by the
719  * body generator that allocated the body.
720  * \param data The subscription data used to populate the body. The type is
721  * determined by the content type.
722  */
723  int (*supplement_body)(void *body, void *data);
724  AST_LIST_ENTRY(ast_sip_pubsub_body_supplement) list;
725 };
726 
727 /*!
728  * \since 13.0.0
729  * \brief Generate body content for a PUBLISH or NOTIFY
730  *
731  * This function takes a pre-allocated body and calls into registered body
732  * generators in order to fill in the body with appropriate details.
733  * The primary body generator will be called first, followed by the
734  * supplementary body generators
735  *
736  * \param content_type The content type of the body
737  * \param content_subtype The content subtype of the body
738  * \param data The data associated with body generation.
739  * \param[out] str The string representation of the generated body
740  * \retval 0 Success
741  * \retval non-zero Failure
742  */
743 int ast_sip_pubsub_generate_body_content(const char *content_type,
744  const char *content_subtype, struct ast_sip_body_data *data, struct ast_str **str);
745 
746 /*!
747  * \brief Is a body generator registered for the given type/subtype.
748  * \since 14.0.0
749  *
750  * \param type The content type of the body
751  * \param subtype The content subtype of the body
752  *
753  * \note In "plain/text", "plain" is the type and "text" is the subtype.
754  *
755  * \retval non-zero if a generator is registered.
756  */
757 int ast_sip_pubsub_is_body_generator_registered(const char *type, const char *subtype);
758 
759 /*!
760  * \since 13.0.0
761  * \brief Register a body generator with the pubsub core.
762  *
763  * This may fail if an attempt is made to register a primary body supplement
764  * for a given content type if a primary body supplement for that content type
765  * has already been registered.
766  *
767  * \param generator Body generator to register
768  * \retval 0 Success
769  * \retval -1 Failure
770  */
771 int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator *generator);
772 
773 /*!
774  * \since 13.0.0
775  * \brief Unregister a body generator with the pubsub core.
776  *
777  * \param generator Body generator to unregister
778  */
779 void ast_sip_pubsub_unregister_body_generator(struct ast_sip_pubsub_body_generator *generator);
780 
781 /*!
782  * \since 13.0.0
783  * \brief Register a body generator with the pubsub core.
784  *
785  * This may fail if an attempt is made to register a primary body supplement
786  * for a given content type if a primary body supplement for that content type
787  * has already been registered.
788  *
789  * \param supplement Body generator to register
790  * \retval 0 Success
791  * \retval -1 Failure
792  */
793 int ast_sip_pubsub_register_body_supplement(struct ast_sip_pubsub_body_supplement *supplement);
794 
795 /*!
796  * \since 13.0.0
797  * \brief Unregister a body generator with the pubsub core.
798  *
799  * \param supplement Body generator to unregister
800  */
801 void ast_sip_pubsub_unregister_body_supplement(struct ast_sip_pubsub_body_supplement *supplement);
802 
803 /*!
804  * \since 13.0.0
805  * \brief Get the body type used for this subscription
806  */
807 const char *ast_sip_subscription_get_body_type(struct ast_sip_subscription *sub);
808 
809 /*!
810  * \since 13.0.0
811  * \brief Get the body subtype used for this subscription
812  */
813 const char *ast_sip_subscription_get_body_subtype(struct ast_sip_subscription *sub);
814 
815 /*!
816  * \since 13.6.0
817  * \brief Alert the pubsub core that the subscription is ready for destruction
818  *
819  * \param sub The subscription that is complete
820  */
821 void ast_sip_subscription_destroy(struct ast_sip_subscription *sub);
822 
823 #endif /* RES_PJSIP_PUBSUB_H */
const char * event_name
The name of the event this handler deals with.
struct ast_sip_subscriber * subscriber
Pubsub body generator.
const char * type
Content type In "plain/text", "plain" is the type.
const char * body_type
Data used to create bodies for NOTIFY/PUBLISH requests.
struct ast_sip_notifier * notifier
Structure for variables, used for configurations and for channel variables.
int(* new_publication)(struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration)
Called when a PUBLISH to establish a new publication arrives.
Structure for a data store type.
Definition: datastore.h:31
const char * type
Content type In "plain/text", "plain" is the type.
Structure for a data store object.
Definition: datastore.h:64
void(* publish_expire)(struct ast_sip_publication *pub)
Called when a publication has reached its expiration.
const char * subtype
Content subtype In "plain/text", "text" is the subtype.
A set of macros to manage forward-linked lists.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:949
const char * subtype
Content subtype In "plain/text", "text" is the subtype.
Structure representing a "virtual" SIP subscription.
int(* publication_state_change)(struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)
Published resource has changed states.
struct ast_sip_publish_handler * handler
Handler for this publication.
Support for dynamic strings.
Definition: strings.h:623
Callbacks that publication handlers will define.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
A ast_taskprocessor structure is a singleton by name.
Definition: taskprocessor.c:69
Abstract JSON element (object, array, string, int, ...).
Structure representing a SIP publication.
Generic container type.
const char * default_accept
Default body type defined for the event package this notifier handles.
struct ao2_container * publications
Publications.
SIP body description.
Definition: res_pjsip.h:2309
Data for responses to SUBSCRIBEs and NOTIFIEs.