Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Functions | Variables
res_pjsip_publish_asterisk.c File Reference
#include "asterisk.h"
#include <regex.h>
#include <pjsip.h>
#include <pjsip_simple.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_outbound_publish.h"
#include "asterisk/res_pjsip_pubsub.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/mwi.h"
Include dependency graph for res_pjsip_publish_asterisk.c:

Go to the source code of this file.

Data Structures

struct  asterisk_devicestate_publisher_state
 Structure which contains Asterisk device state publisher state information. More...
 
struct  asterisk_mwi_publisher_state
 Structure which contains Asterisk mailbox publisher state information. More...
 
struct  asterisk_publication_config
 Structure which contains Asterisk publication information. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void asterisk_devicestate_publisher_state_destroy (void *obj)
 Destroy callback for Asterisk devicestate publisher state information from datastore. More...
 
static void asterisk_mwi_publisher_state_destroy (void *obj)
 Destroy callback for Asterisk mwi publisher state information from datastore. More...
 
static void * asterisk_publication_config_alloc (const char *name)
 Allocator function for Asterisk publication configuration. More...
 
static void asterisk_publication_config_destroy (void *obj)
 Destructor function for Asterisk publication configuration. More...
 
static int asterisk_publication_devicestate (struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
 
static int asterisk_publication_devicestate_refresh (struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
 
static int asterisk_publication_devicestate_state_change (struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)
 
static int asterisk_publication_mailboxstate (struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
 
static int asterisk_publication_mwi_refresh (struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
 
static int asterisk_publication_mwi_state_change (struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)
 
static int asterisk_publication_new (struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration)
 
static void asterisk_publication_send_refresh (void)
 Internal function to send refresh requests to all publications. More...
 
static void asterisk_publisher_devstate_cb (void *data, struct stasis_subscription *sub, struct stasis_message *msg)
 Callback function for device state events. More...
 
static void asterisk_publisher_mwistate_cb (void *data, struct stasis_subscription *sub, struct stasis_message *msg)
 Callback function for mailbox state events. More...
 
static int asterisk_start_devicestate_publishing (struct ast_sip_outbound_publish *configuration, struct ast_sip_outbound_publish_client *client)
 
static int asterisk_start_mwi_publishing (struct ast_sip_outbound_publish *configuration, struct ast_sip_outbound_publish_client *client)
 
static int asterisk_stop_devicestate_publishing (struct ast_sip_outbound_publish_client *client)
 
static int asterisk_stop_mwi_publishing (struct ast_sip_outbound_publish_client *client)
 
static int build_regex (regex_t *regex, const char *text)
 
static int cached_devstate_cb (void *obj, void *arg, int flags)
 
static int cached_mwistate_cb (void *obj, void *arg, int flags)
 
static int load_module (void)
 
static int regex_filter_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int reload_module (void)
 
static int send_refresh_cb (void *obj, void *arg, int flags)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Asterisk Event PUBLISH Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND + 5, .requires = "res_pjsip,res_pjsip_outbound_publish,res_pjsip_pubsub", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
struct ast_sip_publish_handler asterisk_devicestate_publication_handler
 
struct ast_sip_event_publisher_handler asterisk_devicestate_publisher_handler
 
static const struct ast_datastore_info asterisk_devicestate_publisher_state_datastore
 Datastore for attaching devicestate publisher state information. More...
 
struct ast_sip_publish_handler asterisk_mwi_publication_handler
 
struct ast_sip_event_publisher_handler asterisk_mwi_publisher_handler
 
static const struct ast_datastore_info asterisk_mwi_publisher_state_datastore
 Datastore for attaching devicestate publisher state information. More...
 

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 964 of file res_pjsip_publish_asterisk.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 964 of file res_pjsip_publish_asterisk.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 964 of file res_pjsip_publish_asterisk.c.

◆ asterisk_devicestate_publisher_state_destroy()

static void asterisk_devicestate_publisher_state_destroy ( void *  obj)
static

Destroy callback for Asterisk devicestate publisher state information from datastore.

Definition at line 156 of file res_pjsip_publish_asterisk.c.

157{
158 struct asterisk_devicestate_publisher_state *publisher_state = obj;
159
160 ao2_cleanup(publisher_state->client);
161
162 if (publisher_state->device_state_filter) {
163 regfree(&publisher_state->device_state_regex);
164 }
165}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
Structure which contains Asterisk device state publisher state information.
regex_t device_state_regex
Regex used for filtering outbound device state.
struct ast_sip_outbound_publish_client * client
The publish client to send PUBLISH messages on.
unsigned int device_state_filter
Device state should be filtered.

References ao2_cleanup, asterisk_devicestate_publisher_state::client, asterisk_devicestate_publisher_state::device_state_filter, and asterisk_devicestate_publisher_state::device_state_regex.

◆ asterisk_mwi_publisher_state_destroy()

static void asterisk_mwi_publisher_state_destroy ( void *  obj)
static

Destroy callback for Asterisk mwi publisher state information from datastore.

Definition at line 174 of file res_pjsip_publish_asterisk.c.

175{
176 struct asterisk_mwi_publisher_state *publisher_state = obj;
177
178 ao2_cleanup(publisher_state->client);
179
180 if (publisher_state->mailbox_state_filter) {
181 regfree(&publisher_state->mailbox_state_regex);
182 }
183}
Structure which contains Asterisk mailbox publisher state information.
regex_t mailbox_state_regex
Regex used for filtering outbound mailbox state.
struct ast_sip_outbound_publish_client * client
The publish client to send PUBLISH messages on.
unsigned int mailbox_state_filter
Mailbox state should be filtered.

References ao2_cleanup, asterisk_mwi_publisher_state::client, asterisk_mwi_publisher_state::mailbox_state_filter, and asterisk_mwi_publisher_state::mailbox_state_regex.

◆ asterisk_publication_config_alloc()

static void * asterisk_publication_config_alloc ( const char *  name)
static

Allocator function for Asterisk publication configuration.

Definition at line 849 of file res_pjsip_publish_asterisk.c.

850{
853
854 if (!config || ast_string_field_init(config, 256)) {
856 return NULL;
857 }
858
859 return config;
860}
static const char config[]
Definition: chan_ooh323.c:111
static void asterisk_publication_config_destroy(void *obj)
Destructor function for Asterisk publication configuration.
#define NULL
Definition: resample.c:96
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Structure which contains Asterisk publication information.

References ao2_cleanup, ast_sorcery_generic_alloc(), ast_string_field_init, asterisk_publication_config_destroy(), config, and NULL.

Referenced by load_module().

◆ asterisk_publication_config_destroy()

static void asterisk_publication_config_destroy ( void *  obj)
static

Destructor function for Asterisk publication configuration.

Definition at line 841 of file res_pjsip_publish_asterisk.c.

842{
844
846}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory, and config.

Referenced by asterisk_publication_config_alloc().

◆ asterisk_publication_devicestate()

static int asterisk_publication_devicestate ( struct ast_sip_publication pub,
struct asterisk_publication_config config,
struct ast_eid pubsub_eid,
struct ast_json json 
)
static

Definition at line 514 of file res_pjsip_publish_asterisk.c.

516{
517 const char *device = ast_json_string_get(ast_json_object_get(json, "device"));
518 const char *state = ast_json_string_get(ast_json_object_get(json, "state"));
519 int cachable = ast_json_integer_get(ast_json_object_get(json, "cachable"));
520
521 if (!config->device_state) {
522 ast_debug(2, "Received device state event for resource '%s' but it is not configured to accept them\n",
524 return 0;
525 }
526
527 if (ast_strlen_zero(device) || ast_strlen_zero(state)) {
528 ast_debug(1, "Received incomplete device state event for resource '%s'\n",
530 return -1;
531 }
532
533 if (config->device_state_filter && regexec(&config->device_state_regex, device, 0, NULL, 0)) {
534 ast_debug(2, "Received device state on resource '%s' for device '%s' but it has been filtered out\n",
536 return 0;
537 }
538
541 pubsub_eid);
542
543 return 0;
544}
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
@ AST_DEVSTATE_NOT_CACHABLE
Definition: devicestate.h:69
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
Definition: devicestate.c:263
int ast_publish_device_state_full(const char *device, enum ast_device_state state, enum ast_devstate_cache cachable, struct ast_eid *eid)
Publish a device state update with EID.
Definition: devicestate.c:712
#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.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:332
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_debug, AST_DEVSTATE_CACHABLE, AST_DEVSTATE_NOT_CACHABLE, ast_devstate_val(), ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_publish_device_state_full(), ast_sorcery_object_get_id(), ast_strlen_zero(), config, and NULL.

Referenced by asterisk_publication_devicestate_state_change().

◆ asterisk_publication_devicestate_refresh()

static int asterisk_publication_devicestate_refresh ( struct ast_sip_publication pub,
struct asterisk_publication_config config,
struct ast_eid pubsub_eid,
struct ast_json json 
)
static

Definition at line 581 of file res_pjsip_publish_asterisk.c.

583{
584 struct ast_sip_outbound_publish_client *client;
585 struct ast_datastore *datastore;
586 struct ao2_container *cached;
587
588 if (ast_strlen_zero(config->devicestate_publish)) {
589 return 0;
590 }
591
592 client = ast_sip_publish_client_get(config->devicestate_publish);
593 if (!client) {
594 ast_log(LOG_ERROR, "Received refresh request for devicestate on publication '%s' but publish '%s' is not available\n",
595 ast_sorcery_object_get_id(config), config->devicestate_publish);
596 return 0;
597 }
598
599 datastore = ast_sip_publish_client_get_datastore(client, "asterisk-devicestate-publisher");
600 if (!datastore) {
601 ao2_ref(client, -1);
602 return 0;
603 }
604
606 if (cached) {
607 ao2_callback(cached, OBJ_NODATA, cached_devstate_cb, datastore);
608 ao2_ref(cached, -1);
609 }
610 ao2_ref(client, -1);
611 ao2_ref(datastore, -1);
612
613 return 0;
614}
#define ast_log
Definition: astobj2.c:42
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_NODATA
Definition: astobj2.h:1044
struct stasis_cache * ast_device_state_cache(void)
Backend cache for ast_device_state_topic_cached()
Definition: devicestate.c:676
#define LOG_ERROR
struct ast_sip_outbound_publish_client * ast_sip_publish_client_get(const char *name)
Find a publish client using its name.
struct ast_datastore * ast_sip_publish_client_get_datastore(struct ast_sip_outbound_publish_client *client, const char *name)
Retrieve an event publisher datastore.
static int cached_devstate_cb(void *obj, void *arg, int flags)
struct ao2_container * stasis_cache_dump(struct stasis_cache *cache, struct stasis_message_type *type)
Dump cached items to a subscription for the ast_eid_default entity.
Definition: stasis_cache.c:736
Generic container type.
Structure for a data store object.
Definition: datastore.h:64
Outbound publish client state information (persists for lifetime of a publish)

References ao2_callback, ao2_ref, ast_device_state_cache(), ast_log, ast_sip_publish_client_get(), ast_sip_publish_client_get_datastore(), ast_sorcery_object_get_id(), ast_strlen_zero(), cached_devstate_cb(), config, LOG_ERROR, NULL, OBJ_NODATA, and stasis_cache_dump().

Referenced by asterisk_publication_devicestate_state_change().

◆ asterisk_publication_devicestate_state_change()

static int asterisk_publication_devicestate_state_change ( struct ast_sip_publication pub,
pjsip_msg_body *  body,
enum ast_sip_publish_state  state 
)
static

Definition at line 616 of file res_pjsip_publish_asterisk.c.

618{
621 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
622 const char *eid, *type;
623 struct ast_eid pubsub_eid;
624 int res = -1;
625
626 /* If no configuration exists for this publication it has most likely been removed, so drop this immediately */
627 if (!config) {
628 return -1;
629 }
630
631 /* If no body exists this is a refresh and can be ignored */
632 if (!body) {
633 return 0;
634 }
635
636 /* We only accept JSON for content */
637 if (!ast_sip_is_content_type(&body->content_type, "application", "json")) {
638 ast_debug(2, "Received unsupported content type for Asterisk event on resource '%s'\n",
640 return -1;
641 }
642
643 json = ast_json_load_buf(body->data, body->len, NULL);
644 if (!json) {
645 ast_debug(1, "Received unparseable JSON event for resource '%s'\n",
647 return -1;
648 }
649
651 if (!eid) {
652 ast_debug(1, "Received event without eid for resource '%s'\n",
654 return -1;
655 }
656 ast_str_to_eid(&pubsub_eid, eid);
657
659 if (!type) {
660 ast_debug(1, "Received event without type for resource '%s'\n",
662 return -1;
663 } else if (!strcmp(type, "devicestate")) {
664 res = asterisk_publication_devicestate(pub, config, &pubsub_eid, json);
665 } else if (!strcmp(type, "refresh")) {
666 res = asterisk_publication_devicestate_refresh(pub, config, &pubsub_eid, json);
667 }
668
669 return res;
670}
static const char type[]
Definition: chan_ooh323.c:109
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
Parse buffer with known length into a JSON object or array.
Definition: json.c:585
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
Checks if the given content type matches type/subtype.
Definition: res_pjsip.c:2248
static int asterisk_publication_devicestate_refresh(struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
static int asterisk_publication_devicestate(struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
const char * ast_sip_publication_get_event_configuration(const struct ast_sip_publication *pub)
Given a publication, get the configuration name for the event type in use.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:813
unsigned char eid[6]
Definition: utils.h:814
Abstract JSON element (object, array, string, int, ...).
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.
Definition: utils.c:3077

References ao2_cleanup, ast_debug, ast_json_load_buf(), ast_json_object_get(), ast_json_string_get(), ast_json_unref(), ast_sip_get_sorcery(), ast_sip_is_content_type(), ast_sip_publication_get_event_configuration(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_id(), ast_str_to_eid(), asterisk_publication_devicestate(), asterisk_publication_devicestate_refresh(), config, ast_eid::eid, NULL, RAII_VAR, and type.

◆ asterisk_publication_mailboxstate()

static int asterisk_publication_mailboxstate ( struct ast_sip_publication pub,
struct asterisk_publication_config config,
struct ast_eid pubsub_eid,
struct ast_json json 
)
static

Definition at line 546 of file res_pjsip_publish_asterisk.c.

548{
549 const char *uniqueid = ast_json_string_get(ast_json_object_get(json, "uniqueid"));
550 int old_msgs = ast_json_integer_get(ast_json_object_get(json, "old"));
551 int new_msgs = ast_json_integer_get(ast_json_object_get(json, "new"));
552 char *item_id;
553 const char *mailbox;
554
555 if (!config->mailbox_state) {
556 ast_debug(2, "Received mailbox state event for resource '%s' but it is not configured to accept them\n",
558 return 0;
559 }
560
561 if (ast_strlen_zero(uniqueid)) {
562 ast_debug(1, "Received incomplete mailbox state event for resource '%s'\n",
564 return -1;
565 }
566
567 if (config->mailbox_state_filter && regexec(&config->mailbox_state_regex, uniqueid, 0, NULL, 0)) {
568 ast_debug(2, "Received mailbox state on resource '%s' for uniqueid '%s' but it has been filtered out\n",
570 return 0;
571 }
572
573 item_id = ast_strdupa(uniqueid);
574 mailbox = strsep(&item_id, "@");
575
576 ast_publish_mwi_state_full(mailbox, item_id, new_msgs, old_msgs, NULL, pubsub_eid);
577
578 return 0;
579}
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_publish_mwi_state_full(const char *mailbox, const char *context, int new_msgs, int old_msgs, const char *channel_id, struct ast_eid *eid)
Publish a MWI state update via stasis with all parameters.
Definition: mwi.c:393

References ast_debug, ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_publish_mwi_state_full(), ast_sorcery_object_get_id(), ast_strdupa, ast_strlen_zero(), config, voicemailpwcheck::mailbox, NULL, and strsep().

Referenced by asterisk_publication_mwi_state_change().

◆ asterisk_publication_mwi_refresh()

static int asterisk_publication_mwi_refresh ( struct ast_sip_publication pub,
struct asterisk_publication_config config,
struct ast_eid pubsub_eid,
struct ast_json json 
)
static

Definition at line 672 of file res_pjsip_publish_asterisk.c.

674{
675 struct ast_sip_outbound_publish_client *client;
676 struct ast_datastore *datastore;
677 struct ao2_container *cached;
678
679 if (ast_strlen_zero(config->mailboxstate_publish)) {
680 return 0;
681 }
682
683 client = ast_sip_publish_client_get(config->mailboxstate_publish);
684 if (!client) {
685 ast_log(LOG_ERROR, "Received refresh request for mwi state on publication '%s' but publish '%s' is not available\n",
686 ast_sorcery_object_get_id(config), config->mailboxstate_publish);
687 return 0;
688 }
689
690 datastore = ast_sip_publish_client_get_datastore(client, "asterisk-mwi-publisher");
691 if (!datastore) {
692 ao2_ref(client, -1);
693 return 0;
694 }
695
697 if (cached) {
698 ao2_callback(cached, OBJ_NODATA, cached_mwistate_cb, datastore);
699 ao2_ref(cached, -1);
700 }
701 ao2_ref(client, -1);
702 ao2_ref(datastore, -1);
703
704 return 0;
705}
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition: mwi.c:94
static int cached_mwistate_cb(void *obj, void *arg, int flags)

References ao2_callback, ao2_ref, ast_log, ast_mwi_state_cache(), ast_sip_publish_client_get(), ast_sip_publish_client_get_datastore(), ast_sorcery_object_get_id(), ast_strlen_zero(), cached_mwistate_cb(), config, LOG_ERROR, NULL, OBJ_NODATA, and stasis_cache_dump().

Referenced by asterisk_publication_mwi_state_change().

◆ asterisk_publication_mwi_state_change()

static int asterisk_publication_mwi_state_change ( struct ast_sip_publication pub,
pjsip_msg_body *  body,
enum ast_sip_publish_state  state 
)
static

Definition at line 707 of file res_pjsip_publish_asterisk.c.

709{
712 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
713 const char *eid, *type;
714 struct ast_eid pubsub_eid;
715 int res = -1;
716
717 /* If no configuration exists for this publication it has most likely been removed, so drop this immediately */
718 if (!config) {
719 return -1;
720 }
721
722 /* If no body exists this is a refresh and can be ignored */
723 if (!body) {
724 return 0;
725 }
726
727 /* We only accept JSON for content */
728 if (!ast_sip_is_content_type(&body->content_type, "application", "json")) {
729 ast_debug(2, "Received unsupported content type for Asterisk event on resource '%s'\n",
731 return -1;
732 }
733
734 json = ast_json_load_buf(body->data, body->len, NULL);
735 if (!json) {
736 ast_debug(1, "Received unparseable JSON event for resource '%s'\n",
738 return -1;
739 }
740
742 if (!eid) {
743 ast_debug(1, "Received event without eid for resource '%s'\n",
745 return -1;
746 }
747 ast_str_to_eid(&pubsub_eid, eid);
748
750 if (!type) {
751 ast_debug(1, "Received event without type for resource '%s'\n",
753 return -1;
754 } else if (!strcmp(type, "mailboxstate")) {
755 res = asterisk_publication_mailboxstate(pub, config, &pubsub_eid, json);
756 } else if (!strcmp(type, "refresh")) {
757 res = asterisk_publication_mwi_refresh(pub, config, &pubsub_eid, json);
758 }
759
760 return res;
761}
static int asterisk_publication_mailboxstate(struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)
static int asterisk_publication_mwi_refresh(struct ast_sip_publication *pub, struct asterisk_publication_config *config, struct ast_eid *pubsub_eid, struct ast_json *json)

References ao2_cleanup, ast_debug, ast_json_load_buf(), ast_json_object_get(), ast_json_string_get(), ast_json_unref(), ast_sip_get_sorcery(), ast_sip_is_content_type(), ast_sip_publication_get_event_configuration(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_id(), ast_str_to_eid(), asterisk_publication_mailboxstate(), asterisk_publication_mwi_refresh(), config, ast_eid::eid, NULL, RAII_VAR, and type.

◆ asterisk_publication_new()

static int asterisk_publication_new ( struct ast_sip_endpoint endpoint,
const char *  resource,
const char *  event_configuration 
)
static

Definition at line 501 of file res_pjsip_publish_asterisk.c.

502{
504 event_configuration), ao2_cleanup);
505
506 /* If no inbound Asterisk publication configuration exists reject the PUBLISH */
507 if (!config) {
508 return 404;
509 }
510
511 return 200;
512}

References ao2_cleanup, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_id(), config, and RAII_VAR.

◆ asterisk_publication_send_refresh()

static void asterisk_publication_send_refresh ( void  )
static

Internal function to send refresh requests to all publications.

Definition at line 788 of file res_pjsip_publish_asterisk.c.

789{
791 char eid_str[20];
792 struct ast_json *json;
793 char *text;
794 struct ast_sip_body body = {
795 .type = "application",
796 .subtype = "json",
797 };
798
799 if (!publications) {
800 return;
801 }
802
803 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
804 json = ast_json_pack(
805 "{ s: s, s: s }",
806 "type", "refresh",
807 "eid", eid_str);
808 if (!json) {
809 ao2_ref(publications, -1);
810 return;
811 }
812
814 if (!text) {
815 ast_json_unref(json);
816 ao2_ref(publications, -1);
817 return;
818 }
819 body.body_text = text;
820
821 ao2_callback(publications, OBJ_NODATA, send_refresh_cb, &body);
822
824 ast_json_unref(json);
825 ao2_ref(publications, -1);
826}
char * text
Definition: app_queue.c:1809
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:810
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
static int send_refresh_cb(void *obj, void *arg, int flags)
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123
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.
Definition: sorcery.c:1897
SIP body description.
Definition: res_pjsip.h:2444
const char * type
Definition: res_pjsip.h:2446
const char * body_text
Definition: res_pjsip.h:2450
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:94

References ao2_callback, ao2_ref, ast_eid_default, ast_eid_to_str(), ast_json_dump_string, ast_json_free(), ast_json_pack(), ast_json_unref(), AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_fields(), ast_sip_body::body_text, NULL, OBJ_NODATA, send_refresh_cb(), text, and ast_sip_body::type.

Referenced by load_module(), and reload_module().

◆ asterisk_publisher_devstate_cb()

static void asterisk_publisher_devstate_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Callback function for device state events.

Parameters
datavoid pointer to ast_client structure
sub,msg

Definition at line 196 of file res_pjsip_publish_asterisk.c.

197{
198 struct ast_datastore *datastore = data;
199 struct asterisk_devicestate_publisher_state *publisher_state = datastore->data;
200 struct ast_device_state_message *dev_state;
201 char eid_str[20];
202 struct ast_json *json;
203 char *text;
204 struct ast_sip_body body = {
205 .type = "application",
206 .subtype = "json",
207 };
208
210 return;
211 }
212
213 dev_state = stasis_message_data(msg);
214 if (!dev_state->eid || ast_eid_cmp(&ast_eid_default, dev_state->eid)) {
215 /* If the event is aggregate or didn't originate from this server, don't send it out. */
216 return;
217 }
218
219 if (publisher_state->device_state_filter && regexec(&publisher_state->device_state_regex, dev_state->device, 0, NULL, 0)) {
220 /* Outgoing device state has been filtered and the device name does not match */
221 return;
222 }
223
224 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
225 json = ast_json_pack(
226 "{ s: s, s: s, s: s, s: i, s:s }",
227 "type", "devicestate",
228 "device", dev_state->device,
229 "state", ast_devstate_str(dev_state->state),
230 "cachable", dev_state->cachable,
231 "eid", eid_str);
232 if (!json) {
233 return;
234 }
235
237 if (!text) {
238 ast_json_unref(json);
239 return;
240 }
241 body.body_text = text;
242
243 ast_sip_publish_client_send(publisher_state->client, &body);
244
246 ast_json_unref(json);
247}
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
const char * ast_devstate_str(enum ast_device_state devstate) attribute_pure
Convert device state to text string that is easier to parse.
Definition: devicestate.c:258
struct stasis_forward * sub
Definition: res_corosync.c:240
int ast_sip_publish_client_send(struct ast_sip_outbound_publish_client *client, const struct ast_sip_body *body)
Send an outgoing PUBLISH message using a client.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int stasis_subscription_is_subscribed(const struct stasis_subscription *sub)
Returns whether a subscription is currently subscribed.
Definition: stasis.c:1177
void * data
Definition: datastore.h:66
The structure that contains device state.
Definition: devicestate.h:238
enum ast_device_state state
Definition: devicestate.h:248
const struct ast_eid * eid
The EID of the server where this message originated.
Definition: devicestate.h:246
enum ast_devstate_cache cachable
Definition: devicestate.h:250
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: utils.c:3094

References ast_device_state_message_type(), ast_devstate_str(), ast_eid_cmp(), ast_eid_default, ast_eid_to_str(), ast_json_dump_string, ast_json_free(), ast_json_pack(), ast_json_unref(), ast_sip_publish_client_send(), ast_sip_body::body_text, ast_device_state_message::cachable, asterisk_devicestate_publisher_state::client, ast_datastore::data, ast_device_state_message::device, asterisk_devicestate_publisher_state::device_state_filter, asterisk_devicestate_publisher_state::device_state_regex, ast_device_state_message::eid, NULL, stasis_message_data(), stasis_message_type(), stasis_subscription_is_subscribed(), ast_device_state_message::state, sub, text, and ast_sip_body::type.

Referenced by asterisk_start_devicestate_publishing(), and cached_devstate_cb().

◆ asterisk_publisher_mwistate_cb()

static void asterisk_publisher_mwistate_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Callback function for mailbox state events.

Parameters
datavoid pointer to ast_client structure
sub,msg

Definition at line 254 of file res_pjsip_publish_asterisk.c.

255{
256 struct ast_datastore *datastore = data;
257 struct asterisk_mwi_publisher_state *publisher_state = datastore->data;
258 struct ast_mwi_state *mwi_state;
259 char eid_str[20];
260 struct ast_json *json;
261 char *text;
262 struct ast_sip_body body = {
263 .type = "application",
264 .subtype = "json",
265 };
266
268 return;
269 }
270
271 mwi_state = stasis_message_data(msg);
272 if (ast_eid_cmp(&ast_eid_default, &mwi_state->eid)) {
273 /* If the event is aggregate or didn't originate from this server, don't send it out. */
274 return;
275 }
276
277 if (publisher_state->mailbox_state_filter && regexec(&publisher_state->mailbox_state_regex, mwi_state->uniqueid, 0, NULL, 0)) {
278 /* Outgoing mailbox state has been filtered and the uniqueid does not match */
279 return;
280 }
281
282 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
283 json = ast_json_pack(
284 "{ s: s, s: s, s: i, s: i, s:s }",
285 "type", "mailboxstate",
286 "uniqueid", mwi_state->uniqueid,
287 "old", mwi_state->old_msgs,
288 "new", mwi_state->new_msgs,
289 "eid", eid_str);
290 if (!json) {
291 return;
292 }
293
295 if (!text) {
296 ast_json_unref(json);
297 return;
298 }
299 body.body_text = text;
300
301 ast_sip_publish_client_send(publisher_state->client, &body);
302
304 ast_json_unref(json);
305}
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
The structure that contains MWI state.
Definition: mwi.h:455
int old_msgs
Definition: mwi.h:460
int new_msgs
Definition: mwi.h:459
const ast_string_field uniqueid
Definition: mwi.h:458
struct ast_eid eid
Definition: mwi.h:463

References ast_eid_cmp(), ast_eid_default, ast_eid_to_str(), ast_json_dump_string, ast_json_free(), ast_json_pack(), ast_json_unref(), ast_mwi_state_type(), ast_sip_publish_client_send(), ast_sip_body::body_text, asterisk_mwi_publisher_state::client, ast_datastore::data, ast_mwi_state::eid, asterisk_mwi_publisher_state::mailbox_state_filter, asterisk_mwi_publisher_state::mailbox_state_regex, ast_mwi_state::new_msgs, NULL, ast_mwi_state::old_msgs, stasis_message_data(), stasis_message_type(), stasis_subscription_is_subscribed(), sub, text, ast_sip_body::type, and ast_mwi_state::uniqueid.

Referenced by asterisk_start_mwi_publishing(), and cached_mwistate_cb().

◆ asterisk_start_devicestate_publishing()

static int asterisk_start_devicestate_publishing ( struct ast_sip_outbound_publish configuration,
struct ast_sip_outbound_publish_client client 
)
static

Definition at line 344 of file res_pjsip_publish_asterisk.c.

346{
347 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
348 struct asterisk_devicestate_publisher_state *publisher_state;
349 const char *value;
350 struct ao2_container *cached;
351
353 "asterisk-devicestate-publisher");
354 if (!datastore) {
355 return -1;
356 }
357
358 publisher_state = ast_calloc(1, sizeof(struct asterisk_devicestate_publisher_state));
359 if (!publisher_state) {
360 return -1;
361 }
362 datastore->data = publisher_state;
363
364 value = ast_sorcery_object_get_extended(configuration, "device_state_filter");
365 if (!ast_strlen_zero(value)) {
366 if (build_regex(&publisher_state->device_state_regex, value)) {
367 return -1;
368 }
369 publisher_state->device_state_filter = 1;
370 }
371
372 publisher_state->client = ao2_bump(client);
373
374 if (ast_sip_publish_client_add_datastore(client, datastore)) {
375 return -1;
376 }
377
380 if (!publisher_state->device_state_subscription) {
381 ast_sip_publish_client_remove_datastore(client, "asterisk-devicestate-publisher");
382 ao2_ref(datastore, -1);
383 return -1;
384 }
388
390 ao2_callback(cached, OBJ_NODATA, cached_devstate_cb, datastore);
391 ao2_ref(cached, -1);
392
393 return 0;
394}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
Definition: devicestate.c:671
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
int ast_sip_publish_client_add_datastore(struct ast_sip_outbound_publish_client *client, struct ast_datastore *datastore)
Add a datastore to a SIP event publisher.
void ast_sip_publish_client_remove_datastore(struct ast_sip_outbound_publish_client *client, const char *name)
Remove a publication datastore from an event publisher.
struct ast_datastore * ast_sip_publish_client_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
static void asterisk_publisher_devstate_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Callback function for device state events.
static int build_regex(regex_t *regex, const char *text)
static const struct ast_datastore_info asterisk_devicestate_publisher_state_datastore
Datastore for attaching devicestate publisher state information.
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
Definition: sorcery.c:2335
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
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.
Definition: stasis.c:1050
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1104
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649
struct stasis_subscription * device_state_subscription
Device state subscription.
int value
Definition: syslog.c:37

References ao2_bump, ao2_callback, ao2_cleanup, ao2_ref, ast_calloc, ast_device_state_cache(), ast_device_state_message_type(), ast_device_state_topic_all(), ast_sip_publish_client_add_datastore(), ast_sip_publish_client_alloc_datastore(), ast_sip_publish_client_remove_datastore(), ast_sorcery_object_get_extended(), ast_strlen_zero(), asterisk_devicestate_publisher_state_datastore, asterisk_publisher_devstate_cb(), build_regex(), cached_devstate_cb(), asterisk_devicestate_publisher_state::client, asterisk_devicestate_publisher_state::device_state_filter, asterisk_devicestate_publisher_state::device_state_regex, asterisk_devicestate_publisher_state::device_state_subscription, NULL, OBJ_NODATA, RAII_VAR, stasis_cache_dump(), stasis_subscribe, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), and value.

◆ asterisk_start_mwi_publishing()

static int asterisk_start_mwi_publishing ( struct ast_sip_outbound_publish configuration,
struct ast_sip_outbound_publish_client client 
)
static

Definition at line 423 of file res_pjsip_publish_asterisk.c.

425{
426 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
427 struct asterisk_mwi_publisher_state *publisher_state;
428 const char *value;
429 struct ao2_container *cached;
430
432 if (!datastore) {
433 return -1;
434 }
435
436 publisher_state = ast_calloc(1, sizeof(struct asterisk_mwi_publisher_state));
437 if (!publisher_state) {
438 return -1;
439 }
440 datastore->data = publisher_state;
441
442 value = ast_sorcery_object_get_extended(configuration, "mailbox_state_filter");
443 if (!ast_strlen_zero(value)) {
444 if (build_regex(&publisher_state->mailbox_state_regex, value)) {
445 return -1;
446 }
447 publisher_state->mailbox_state_filter = 1;
448 }
449
450 publisher_state->client = ao2_bump(client);
451
452 if (ast_sip_publish_client_add_datastore(client, datastore)) {
453 return -1;
454 }
455
458 if (!publisher_state->mailbox_state_subscription) {
459 ast_sip_publish_client_remove_datastore(client, "asterisk-mwi-publisher");
460 ao2_ref(datastore, -1);
461 return -1;
462 }
466
468 ao2_callback(cached, OBJ_NODATA, cached_mwistate_cb, datastore);
469 ao2_ref(cached, -1);
470
471 return 0;
472}
struct stasis_topic * ast_mwi_topic_all(void)
Get the Stasis Message Bus API topic for MWI messages.
Definition: mwi.c:89
static void asterisk_publisher_mwistate_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Callback function for mailbox state events.
static const struct ast_datastore_info asterisk_mwi_publisher_state_datastore
Datastore for attaching devicestate publisher state information.
struct stasis_subscription * mailbox_state_subscription
Mailbox state subscription.

References ao2_bump, ao2_callback, ao2_cleanup, ao2_ref, ast_calloc, ast_mwi_state_cache(), ast_mwi_state_type(), ast_mwi_topic_all(), ast_sip_publish_client_add_datastore(), ast_sip_publish_client_alloc_datastore(), ast_sip_publish_client_remove_datastore(), ast_sorcery_object_get_extended(), ast_strlen_zero(), asterisk_mwi_publisher_state_datastore, asterisk_publisher_mwistate_cb(), build_regex(), cached_mwistate_cb(), asterisk_mwi_publisher_state::client, asterisk_mwi_publisher_state::mailbox_state_filter, asterisk_mwi_publisher_state::mailbox_state_regex, asterisk_mwi_publisher_state::mailbox_state_subscription, NULL, OBJ_NODATA, RAII_VAR, stasis_cache_dump(), stasis_subscribe, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), and value.

◆ asterisk_stop_devicestate_publishing()

static int asterisk_stop_devicestate_publishing ( struct ast_sip_outbound_publish_client client)
static

Definition at line 396 of file res_pjsip_publish_asterisk.c.

397{
398 RAII_VAR(struct ast_datastore *, datastore, ast_sip_publish_client_get_datastore(client, "asterisk-devicestate-publisher"),
400 struct asterisk_devicestate_publisher_state *publisher_state;
401
402 if (!datastore) {
403 return 0;
404 }
405
406 publisher_state = datastore->data;
407 if (publisher_state->device_state_subscription) {
409 ao2_ref(datastore, -1);
410 }
411
412 ast_sip_publish_client_remove_datastore(client, "asterisk-devicestate-publisher");
413
414 return 0;
415}
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1161

References ao2_cleanup, ao2_ref, ast_sip_publish_client_get_datastore(), ast_sip_publish_client_remove_datastore(), asterisk_devicestate_publisher_state::client, asterisk_devicestate_publisher_state::device_state_subscription, RAII_VAR, and stasis_unsubscribe_and_join().

◆ asterisk_stop_mwi_publishing()

static int asterisk_stop_mwi_publishing ( struct ast_sip_outbound_publish_client client)
static

Definition at line 474 of file res_pjsip_publish_asterisk.c.

475{
476 RAII_VAR(struct ast_datastore *, datastore, ast_sip_publish_client_get_datastore(client, "asterisk-mwi-publisher"),
478 struct asterisk_mwi_publisher_state *publisher_state;
479
480 if (!datastore) {
481 return 0;
482 }
483
484 publisher_state = datastore->data;
485 if (publisher_state->mailbox_state_subscription) {
487 ao2_ref(datastore, -1);
488 }
489
490 ast_sip_publish_client_remove_datastore(client, "asterisk-mwi-publisher");
491
492 return 0;
493}

References ao2_cleanup, ao2_ref, ast_sip_publish_client_get_datastore(), ast_sip_publish_client_remove_datastore(), asterisk_mwi_publisher_state::client, asterisk_mwi_publisher_state::mailbox_state_subscription, RAII_VAR, and stasis_unsubscribe_and_join().

◆ build_regex()

static int build_regex ( regex_t *  regex,
const char *  text 
)
static

Definition at line 329 of file res_pjsip_publish_asterisk.c.

330{
331 int res;
332
333 if ((res = regcomp(regex, text, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
334 size_t len = regerror(res, regex, NULL, 0);
335 char buf[len];
336 regerror(res, regex, buf, len);
337 ast_log(LOG_ERROR, "Could not compile regex '%s': %s\n", text, buf);
338 return -1;
339 }
340
341 return 0;
342}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References ast_log, buf, len(), LOG_ERROR, NULL, regex(), and text.

Referenced by asterisk_start_devicestate_publishing(), asterisk_start_mwi_publishing(), and regex_filter_handler().

◆ cached_devstate_cb()

static int cached_devstate_cb ( void *  obj,
void *  arg,
int  flags 
)
static

◆ cached_mwistate_cb()

static int cached_mwistate_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 318 of file res_pjsip_publish_asterisk.c.

319{
320 struct stasis_message *msg = obj;
321 struct ast_datastore *datastore = arg;
322 struct asterisk_mwi_publisher_state *publisher_state = datastore->data;
323
325
326 return 0;
327}

References asterisk_publisher_mwistate_cb(), ast_datastore::data, and asterisk_mwi_publisher_state::mailbox_state_subscription.

Referenced by asterisk_publication_mwi_refresh(), and asterisk_start_mwi_publishing().

◆ load_module()

static int load_module ( void  )
static

Definition at line 884 of file res_pjsip_publish_asterisk.c.

885{
887 ast_log(LOG_ERROR, "Entity ID is not set.\n");
889 }
890
891 ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_publish_asterisk");
892 ast_sorcery_apply_default(ast_sip_get_sorcery(), "asterisk-publication", "config", "pjsip.conf,criteria=type=asterisk-publication");
893
895 ast_log(LOG_ERROR, "Unable to register 'asterisk-publication' type with sorcery\n");
897 }
898
899 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "type", "", OPT_NOOP_T, 0, 0);
900 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "devicestate_publish", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct asterisk_publication_config, devicestate_publish));
901 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "mailboxstate_publish", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct asterisk_publication_config, mailboxstate_publish));
902 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "device_state", "no", OPT_BOOL_T, 1, FLDSET(struct asterisk_publication_config, device_state));
903 ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "asterisk-publication", "device_state_filter", "", regex_filter_handler, NULL, NULL, 0, 0);
904 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "mailbox_state", "no", OPT_BOOL_T, 1, FLDSET(struct asterisk_publication_config, mailbox_state));
905 ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "asterisk-publication", "mailbox_state_filter", "", regex_filter_handler, NULL, NULL, 0, 0);
906 ast_sorcery_reload_object(ast_sip_get_sorcery(), "asterisk-publication");
907
909 ast_log(LOG_WARNING, "Unable to register event publication handler %s\n",
912 }
914 ast_log(LOG_WARNING, "Unable to register event publication handler %s\n",
918 }
920 ast_log(LOG_WARNING, "Unable to register event publisher handler %s\n",
925 }
927 ast_log(LOG_WARNING, "Unable to register event publisher handler %s\n",
933 }
934
936
938}
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
#define LOG_WARNING
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
void ast_sip_unregister_event_publisher_handler(struct ast_sip_event_publisher_handler *handler)
Unregister a publish handler.
int ast_sip_register_event_publisher_handler(struct ast_sip_event_publisher_handler *handler)
Register an event publisher handler.
struct ast_sip_publish_handler asterisk_devicestate_publication_handler
struct ast_sip_event_publisher_handler asterisk_mwi_publisher_handler
static void asterisk_publication_send_refresh(void)
Internal function to send refresh requests to all publications.
static void * asterisk_publication_config_alloc(const char *name)
Allocator function for Asterisk publication configuration.
static int regex_filter_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
struct ast_sip_event_publisher_handler asterisk_devicestate_publisher_handler
struct ast_sip_publish_handler asterisk_mwi_publication_handler
int ast_sip_register_publish_handler(struct ast_sip_publish_handler *handler)
Register a publish handler.
void ast_sip_unregister_publish_handler(struct ast_sip_publish_handler *handler)
Unregister a publish handler.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
#define ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:455
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
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.
Definition: sorcery.c:1442
const char * event_name
The name of the event this handler deals with.
const char * event_name
The name of the event this handler deals with.
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
Definition: utils.c:3099

References ast_eid_default, ast_eid_is_empty(), ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_sip_get_sorcery(), ast_sip_register_event_publisher_handler(), ast_sip_register_publish_handler(), ast_sip_unregister_event_publisher_handler(), ast_sip_unregister_publish_handler(), ast_sorcery_apply_config, ast_sorcery_apply_default, ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_register, ast_sorcery_reload_object(), asterisk_devicestate_publication_handler, asterisk_devicestate_publisher_handler, asterisk_mwi_publication_handler, asterisk_mwi_publisher_handler, asterisk_publication_config_alloc(), asterisk_publication_send_refresh(), asterisk_publication_config::device_state, asterisk_publication_config::devicestate_publish, ast_sip_event_publisher_handler::event_name, ast_sip_publish_handler::event_name, FLDSET, LOG_ERROR, LOG_WARNING, asterisk_publication_config::mailbox_state, asterisk_publication_config::mailboxstate_publish, NULL, OPT_BOOL_T, OPT_NOOP_T, OPT_STRINGFIELD_T, regex_filter_handler(), and STRFLDSET.

◆ regex_filter_handler()

static int regex_filter_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 862 of file res_pjsip_publish_asterisk.c.

863{
865 int res = -1;
866
867 if (ast_strlen_zero(var->value)) {
868 return 0;
869 }
870
871 if (!strcmp(var->name, "device_state_filter")) {
872 if (!(res = build_regex(&config->device_state_regex, var->value))) {
873 config->device_state_filter = 1;
874 }
875 } else if (!strcmp(var->name, "mailbox_state_filter")) {
876 if (!(res = build_regex(&config->mailbox_state_regex, var->value))) {
877 config->mailbox_state_filter = 1;
878 }
879 }
880
881 return res;
882}
#define var
Definition: ast_expr2f.c:605

References ast_strlen_zero(), build_regex(), config, and var.

Referenced by load_module().

◆ reload_module()

static int reload_module ( void  )
static

◆ send_refresh_cb()

static int send_refresh_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 763 of file res_pjsip_publish_asterisk.c.

764{
766 struct ast_sip_outbound_publish_client *client;
767
768 if (!ast_strlen_zero(config->devicestate_publish)) {
769 client = ast_sip_publish_client_get(config->devicestate_publish);
770 if (client) {
771 ast_sip_publish_client_send(client, arg);
772 ao2_ref(client, -1);
773 }
774 }
775
776 if (!ast_strlen_zero(config->mailboxstate_publish)) {
777 client = ast_sip_publish_client_get(config->mailboxstate_publish);
778 if (client) {
779 ast_sip_publish_client_send(client, arg);
780 ao2_ref(client, -1);
781 }
782 }
783
784 return 0;
785}

References ao2_ref, ast_sip_publish_client_get(), ast_sip_publish_client_send(), ast_strlen_zero(), and config.

Referenced by asterisk_publication_send_refresh().

◆ unload_module()

static int unload_module ( void  )
static

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Asterisk Event PUBLISH Support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND + 5, .requires = "res_pjsip,res_pjsip_outbound_publish,res_pjsip_pubsub", }
static

Definition at line 964 of file res_pjsip_publish_asterisk.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 964 of file res_pjsip_publish_asterisk.c.

◆ asterisk_devicestate_publication_handler

struct ast_sip_publish_handler asterisk_devicestate_publication_handler
Initial value:
= {
.event_name = "asterisk-devicestate",
.new_publication = asterisk_publication_new,
.publication_state_change = asterisk_publication_devicestate_state_change,
}
static int asterisk_publication_devicestate_state_change(struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)
static int asterisk_publication_new(struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration)

Definition at line 828 of file res_pjsip_publish_asterisk.c.

Referenced by load_module(), and unload_module().

◆ asterisk_devicestate_publisher_handler

struct ast_sip_event_publisher_handler asterisk_devicestate_publisher_handler
Initial value:
= {
.event_name = "asterisk-devicestate",
}
static int asterisk_stop_devicestate_publishing(struct ast_sip_outbound_publish_client *client)
static int asterisk_start_devicestate_publishing(struct ast_sip_outbound_publish *configuration, struct ast_sip_outbound_publish_client *client)

Definition at line 417 of file res_pjsip_publish_asterisk.c.

Referenced by load_module(), and unload_module().

◆ asterisk_devicestate_publisher_state_datastore

const struct ast_datastore_info asterisk_devicestate_publisher_state_datastore
static
Initial value:
= {
.type = "asterisk-devicestate-publisher",
}
static void asterisk_devicestate_publisher_state_destroy(void *obj)
Destroy callback for Asterisk devicestate publisher state information from datastore.

Datastore for attaching devicestate publisher state information.

Definition at line 168 of file res_pjsip_publish_asterisk.c.

Referenced by asterisk_start_devicestate_publishing().

◆ asterisk_mwi_publication_handler

struct ast_sip_publish_handler asterisk_mwi_publication_handler
Initial value:
= {
.event_name = "asterisk-mwi",
.new_publication = asterisk_publication_new,
.publication_state_change = asterisk_publication_mwi_state_change,
}
static int asterisk_publication_mwi_state_change(struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)

Definition at line 834 of file res_pjsip_publish_asterisk.c.

Referenced by load_module(), and unload_module().

◆ asterisk_mwi_publisher_handler

struct ast_sip_event_publisher_handler asterisk_mwi_publisher_handler
Initial value:
= {
.event_name = "asterisk-mwi",
.start_publishing = asterisk_start_mwi_publishing,
.stop_publishing = asterisk_stop_mwi_publishing,
}
static int asterisk_start_mwi_publishing(struct ast_sip_outbound_publish *configuration, struct ast_sip_outbound_publish_client *client)
static int asterisk_stop_mwi_publishing(struct ast_sip_outbound_publish_client *client)

Definition at line 495 of file res_pjsip_publish_asterisk.c.

Referenced by load_module(), and unload_module().

◆ asterisk_mwi_publisher_state_datastore

const struct ast_datastore_info asterisk_mwi_publisher_state_datastore
static
Initial value:
= {
.type = "asterisk-mwi-publisher",
}
static void asterisk_mwi_publisher_state_destroy(void *obj)
Destroy callback for Asterisk mwi publisher state information from datastore.

Datastore for attaching devicestate publisher state information.

Definition at line 186 of file res_pjsip_publish_asterisk.c.

Referenced by asterisk_start_mwi_publishing().