29#include <pjsip_simple.h> 
   51#define STASIS_BUCKETS 13 
   54#define MWI_TYPE "application" 
   55#define MWI_SUBTYPE "simple-message-summary" 
   57#define MWI_DATASTORE "MWI datastore" 
   60#define MWI_SERIALIZER_POOL_SIZE 8 
   63#define MAX_UNLOAD_TIMEOUT_TIME 10  
   71        const char *resource);
 
  149    if (!mwi_stasis_sub) {
 
  169    return mwi_stasis_sub;
 
 
  196    const char *right_key = arg;
 
  201        right_key = sub_right->
mailbox;
 
  204        cmp = strcmp(sub_left->
mailbox, right_key);
 
  207        cmp = strncmp(sub_left->
mailbox, right_key, strlen(right_key));
 
 
  223    ast_debug(3, 
"Destroying MWI subscription for endpoint %s\n", 
sub->id);
 
  224    if (
sub->is_solicited) {
 
 
  245    strcpy(
sub->id, endpoint_id);
 
  260    if (!
sub->stasis_subs) {
 
 
  303    const char *right_key = arg;
 
  308        right_key = sub_right->
id;
 
  311        cmp = strcmp(sub_left->
id, right_key);
 
  314        cmp = strncmp(sub_left->
id, right_key, strlen(right_key));
 
 
  348    pjsip_sip_uri *account_uri;
 
  349    const char *vm_exten;
 
  354        vm_exten = voicemail_extension;
 
  358        account_uri = pjsip_uri_clone(pool, local_uri);
 
  359        pj_strdup2(pool, &account_uri->user, vm_exten);
 
 
  378    const char *state_name;
 
  379    pjsip_tx_data *tdata;
 
  380    pjsip_sub_state_hdr *sub_state;
 
  381    pjsip_event_hdr *
event;
 
  382    pjsip_from_hdr *from;
 
  383    pjsip_sip_uri *from_uri;
 
  384    const pjsip_hdr *allow_events = pjsip_evsub_get_allow_events_hdr(
NULL);
 
  389        .body_data = mwi_data->
counter,
 
  401        pjsip_tx_data_dec_ref(tdata);
 
  405    from = PJSIP_MSG_FROM_HDR(tdata->msg);
 
  406    from_uri = pjsip_uri_get_uri(from->uri);
 
  417        pjsip_tx_data_dec_ref(tdata);
 
  424    case PJSIP_EVSUB_STATE_ACTIVE:
 
  425        state_name = 
"active";
 
  427    case PJSIP_EVSUB_STATE_TERMINATED:
 
  429        state_name = 
"terminated";
 
  433    sub_state = pjsip_sub_state_hdr_create(tdata->pool);
 
  434    pj_cstr(&sub_state->sub_state, state_name);
 
  435    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) sub_state);
 
  437    event = pjsip_event_hdr_create(tdata->pool);
 
  438    pj_cstr(&
event->event_type, 
"message-summary");
 
  439    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) 
event);
 
  441    pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_shallow_clone(tdata->pool, allow_events));
 
 
  480            ast_debug(1, 
"Found an aor (%s) that matches voicemail_extension %s\n", aor_name, resource);
 
 
  499        ast_log(
LOG_WARNING, 
"Unable to send unsolicited MWI to %s because endpoint does not exist\n",
 
  504        ast_log(
LOG_WARNING, 
"Unable to send unsolicited MWI to %s because the endpoint has no" 
  505                " configured AORs\n", 
sub->id);
 
  511    ast_debug(5, 
"Sending unsolicited MWI NOTIFY to endpoint %s, new messages: %d, old messages: %d\n",
 
  530            ast_debug(1, 
"No contacts bound to AOR %s. Cannot send unsolicited MWI until a contact registers.\n", aor_name);
 
 
  543        .message_account[0] = 
'\0',
 
  547        .body_data = &counter,
 
  552    if (
sub->is_solicited) {
 
  559        if (aor && dlg && sip_uri) {
 
 
  578        ast_debug(3, 
"Removing stasis subscription to mailbox %s\n", mwi_stasis->
mailbox);
 
 
  596    if (!mwi_datastore) {
 
  618    if (unsolicited_mwi && endpoint) {
 
 
  646    if (!mwi_datastore) {
 
 
  711    return *mwi_stasis ? 1 : 0;
 
 
  752    ast_debug(1, 
"Unsolicited subscription being replaced by solicited for " 
 
  769static int send_notify(
void *obj, 
void *arg, 
int flags);
 
  858    if (unsolicited_mwi) {
 
  869            ast_debug(1, 
"Endpoint '%s' already configured for unsolicited MWI for mailbox '%s'. " 
  873            if (unsolicited_mwi) {
 
  881    if (unsolicited_mwi) {
 
 
  909        if (!mwi_stasis_sub) {
 
 
  975        const char *resource)
 
  988        ast_debug(1, 
"Unable to locate aor %s. MWI subscription failed.\n", resource);
 
  993        ast_debug(1, 
"AOR %s has no configured mailboxes. MWI subscription failed.\n",
 
 
 1032    if (solicited_mwi) {
 
 
 1051    if (!mwi_datastore) {
 
 1066        if (dlg && sip_uri) {
 
 
 1104    if (!mwi_datastore) {
 
 
 1211        if (aggregate_sub && !recreate) {
 
 1215        if (!aggregate_sub) {
 
 1217            if (!aggregate_sub) {
 
 1231    if (solicited_mwi) {
 
 1250        if (mwi_stasis_sub) {
 
 1254        if (!aggregate_sub) {
 
 1262        if (aggregate_sub && !sub_added) {
 
 1268    if (aggregate_sub) {
 
 1274            if (send_now && sub_added) {
 
 1280    if (solicited_mwi) {
 
 
 1309    if (!unsolicited_mwi) {
 
 
 1346    const char *aor = arg;
 
 
 1383    if (!unsolicited_mwi) {
 
 
 1439    if (found_contact) {
 
 1445    if (!unsolicited_mwi) {
 
 
 1474    if (unsolicited_mwi) {
 
 
 1495    if (strcmp(
type, 
"FullyBooted")) {
 
 
 1545        if (unsolicited_mwi) {
 
 
 1579        ast_log(
AST_LOG_WARNING, 
"Failed to create MWI serializer pool. The default SIP pool will be used for MWI\n");
 
 1584    if (!mwi_container) {
 
 1593    if (!mwi_container) {
 
 
 1636    .
requires = 
"res_pjsip,res_pjsip_pubsub",
 
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
int ast_shutdown_final(void)
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_iterator_next(iter)
#define AO2_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_callback_data(container, flags, cb_fn, arg, data)
#define ao2_unlink(container, obj)
Remove an object from a container.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_global_obj_replace(holder, obj)
Replace an ao2 object in the global holder.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
static struct ao2_container * endpoints
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
Asterisk module definitions.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_subscription * ast_mwi_subscriber_subscription(struct ast_mwi_subscriber *sub)
Retrieve the stasis MWI topic subscription if available.
void * ast_mwi_unsubscribe_and_join(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic, block until the final message is received, and then unsubscribe fr...
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
struct ast_mwi_state * ast_mwi_subscriber_data(struct ast_mwi_subscriber *sub)
Retrieves the state data object associated with the MWI subscriber.
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
struct ao2_container * container
static struct stasis_subscription * mwi_sub
struct ast_sip_contact * ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list)
Retrieve the first bound contact from a list of AORs.
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
int ast_sip_for_each_aor(const char *aors, ao2_callback_fn on_aor, void *arg)
For every aor in the comma separated aors string call the given 'on_aor' handler.
char * ast_sip_get_default_voicemail_extension(void)
Retrieve the default voicemail extension.
int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending a SIP request.
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
unsigned int ast_sip_get_mwi_disable_initial_unsolicited(void)
Retrieve the global setting 'disable sending unsolicited mwi on startup'.
struct ast_threadpool * ast_sip_threadpool(void)
Retrieve the SIP threadpool object.
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
int ast_sip_get_mwi_tps_queue_low(void)
Retrieve the global MWI taskprocessor low water clear alert level.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
unsigned int ast_sip_get_mwi_tps_queue_high(void)
Retrieve the global MWI taskprocessor high water alert trigger level.
struct ao2_container * ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
Retrieve all contacts currently available for an AOR.
static void mwi_contact_deleted(const void *object)
Function called when a contact is deleted.
static int mwi_new_subscribe(struct ast_sip_endpoint *endpoint, const char *resource)
static void send_unsolicited_mwi_notify(struct mwi_subscription *sub, struct ast_sip_message_accumulator *counter)
static void mwi_subscription_destructor(void *obj)
static struct ast_sorcery_observer global_observer
static struct mwi_subscription * mwi_create_subscription(struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub)
static int send_notify(void *obj, void *arg, int flags)
static void mwi_to_ami(struct ast_sip_subscription *sub, struct ast_str **buf)
static void global_loaded(const char *object_type)
static int stasis_sub_hash(const void *obj, const int flags)
static void mwi_contact_added(const void *object)
Function called when a contact is added.
static int unsubscribe(void *obj, void *arg, int flags)
static void send_mwi_notify(struct mwi_subscription *sub)
static void set_voicemail_extension(pj_pool_t *pool, pjsip_sip_uri *local_uri, struct ast_sip_message_accumulator *counter, const char *voicemail_extension)
static int mwi_on_aor(void *obj, void *arg, int flags)
static int allow_and_or_replace_unsolicited(struct ast_sip_endpoint *endpoint, const char *mailbox, struct ao2_container *unsolicited_mwi)
#define MAX_UNLOAD_TIMEOUT_TIME
static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flags)
static int get_message_count(void *obj, void *arg, int flags)
static int has_mwi_subscription(struct ao2_container *container, struct ast_sip_endpoint *endpoint, const char *mailbox, struct mwi_subscription **mwi_sub, struct mwi_stasis_subscription **mwi_stasis)
static int add_mwi_datastore(struct mwi_subscription *sub)
static void mwi_contact_updated(const void *object)
Function called when a contact is updated.
static void mwi_subscription_shutdown(struct ast_sip_subscription *sub)
static int create_unsolicited_mwi_subscriptions(struct ast_sip_endpoint *endpoint, int recreate, int send_now, struct ao2_container *unsolicited_mwi, struct ao2_container *solicited_mwi)
static struct mwi_subscription * mwi_subscription_alloc(struct ast_sip_endpoint *endpoint, unsigned int is_solicited, struct ast_sip_subscription *sip_sub)
static struct ast_datastore_info mwi_ds_info
static struct mwi_stasis_subscription * mwi_stasis_subscription_alloc(const char *mailbox, struct mwi_subscription *mwi_sub)
static int mwi_subscription_established(struct ast_sip_subscription *sub)
static struct ast_serializer_pool * mwi_serializer_pool
static void mwi_ds_destroy(void *data)
static char * default_voicemail_extension
static int is_unsolicited_allowed(struct ast_sip_endpoint *endpoint, const char *mailbox, struct ao2_container *unsolicited_mwi, struct ao2_container *solicited_mwi)
static const struct ast_sorcery_observer mwi_contact_observer
Observer for contacts so unsolicited MWI is sent when a contact changes.
static void create_mwi_subscriptions(void)
static struct mwi_subscription * mwi_subscribe_all(struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub)
static void * mwi_get_notify_data(struct ast_sip_subscription *sub)
static struct mwi_subscription * mwi_subscribe_single(struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub, const char *name)
static struct ast_sip_notifier mwi_notifier
static void mwi_startup_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Event callback which fires initial unsolicited MWI NOTIFY messages when we're fully booted.
static int mwi_validate_for_aor(void *obj, void *arg, int flags)
Determine if an endpoint is a candidate to be able to subscribe for MWI.
static int send_contact_notify(void *obj, void *arg, int flags)
Function called to send MWI NOTIFY on any unsolicited mailboxes relating to this AOR.
static void mwi_contact_changed(const struct ast_sip_contact *contact)
Create mwi subscriptions and notify.
static int serialized_notify(void *userdata)
static int mwi_sub_cmp(void *obj, void *arg, int flags)
static struct ast_sip_aor * find_aor_for_resource(struct ast_sip_endpoint *endpoint, const char *resource)
static int serialized_cleanup(void *userdata)
static int unsubscribe_stasis(void *obj, void *arg, int flags)
static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
static int load_module(void)
static void mwi_subscription_mailboxes_str(struct ao2_container *stasis_subs, struct ast_str **str)
static int stasis_sub_cmp(void *obj, void *arg, int flags)
static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, void *data, int flags)
static int unload_module(void)
static int mwi_sub_hash(const void *obj, const int flags)
static int send_initial_notify_all(void *obj)
Task invoked to send initial MWI NOTIFY for unsolicited.
#define MWI_SERIALIZER_POOL_SIZE
static struct ast_sip_subscription_handler mwi_handler
struct ast_sip_endpoint * ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub)
Get the endpoint that is associated with this subscription.
void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler)
Unregister a subscription handler.
int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler)
Register a subscription handler.
void ast_sip_subscription_destroy(struct ast_sip_subscription *sub)
Alert the pubsub core that the subscription is ready for destruction.
void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name)
Remove a subscription datastore from the subscription.
int ast_sip_pubsub_generate_body_content(const char *content_type, const char *content_subtype, struct ast_sip_body_data *data, struct ast_str **str)
Generate body content for a PUBLISH or NOTIFY.
struct ast_datastore * ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
struct ast_taskprocessor * ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub)
Get the serializer for the subscription.
int ast_sip_subscription_notify(struct ast_sip_subscription *sub, struct ast_sip_body_data *notify_data, int terminate)
Notify a SIP subscription of a state change.
int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore)
Add a datastore to a SIP subscription.
const char * ast_sip_subscription_get_resource_name(struct ast_sip_subscription *sub)
Get the name of the subscribed resource.
pjsip_sip_uri * ast_sip_subscription_get_sip_uri(struct ast_sip_subscription *sub)
Retrieve the local sip uri for this subscription.
#define AST_SIP_MESSAGE_ACCUMULATOR
pjsip_dialog * ast_sip_subscription_get_dialog(struct ast_sip_subscription *sub)
Get the pjsip dialog that is associated with this subscription.
struct ast_datastore * ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name)
Retrieve a subscription datastore.
struct ast_taskprocessor * ast_serializer_pool_get(struct ast_serializer_pool *pool)
Retrieve a serializer from the pool.
int ast_serializer_pool_set_alerts(struct ast_serializer_pool *pool, long high, long low)
Set taskprocessor alert levels for the serializers in the pool.
struct ast_serializer_pool * ast_serializer_pool_create(const char *name, unsigned int size, struct ast_threadpool *threadpool, int timeout)
Create a serializer pool.
int ast_serializer_pool_destroy(struct ast_serializer_pool *pool)
Destroy the serializer pool.
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
#define stasis_subscribe_pool(topic, callback, data)
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Structure for a data store type.
void(* destroy)(void *data)
Structure for a data store object.
The structure that contains MWI state.
char * voicemail_extension
const ast_string_field mailboxes
Data used to create bodies for NOTIFY/PUBLISH requests.
struct ast_sip_mwi_configuration mwi
An entity with which Asterisk communicates.
const ast_string_field aors
struct ast_sip_endpoint_subscription_configuration subscription
Message counter used for message-summary XML bodies.
char message_account[PJSIP_MAX_URL_SIZE]
char * voicemail_extension
const ast_string_field mailboxes
const ast_string_field fromuser
unsigned int subscribe_replaces_unsolicited
const char * default_accept
Default body type defined for the event package this notifier handles.
Structure representing a "virtual" SIP subscription.
Interface for a sorcery object type observer.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
void(* created)(const void *object)
Callback for when an object is created.
Support for dynamic strings.
A ast_taskprocessor structure is a singleton by name.
Structure for variables, used for configurations and for channel variables.
Wrapper for stasis subscription.
struct ast_mwi_subscriber * mwi_subscriber
struct ast_sip_subscription * sip_sub
unsigned int is_solicited
struct ao2_container * stasis_subs
struct ast_sip_endpoint * endpoint
struct ast_sip_message_accumulator * counter
struct mwi_subscription * sub
An API for managing task processing threads that can be shared across modules.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.