Asterisk - The Open Source Telephony Project GIT-master-2de1a68
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 940 of file res_pjsip_publish_asterisk.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 940 of file res_pjsip_publish_asterisk.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 940 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 132 of file res_pjsip_publish_asterisk.c.

133{
134 struct asterisk_devicestate_publisher_state *publisher_state = obj;
135
136 ao2_cleanup(publisher_state->client);
137
138 if (publisher_state->device_state_filter) {
139 regfree(&publisher_state->device_state_regex);
140 }
141}
#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 150 of file res_pjsip_publish_asterisk.c.

151{
152 struct asterisk_mwi_publisher_state *publisher_state = obj;
153
154 ao2_cleanup(publisher_state->client);
155
156 if (publisher_state->mailbox_state_filter) {
157 regfree(&publisher_state->mailbox_state_regex);
158 }
159}
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 825 of file res_pjsip_publish_asterisk.c.

826{
829
830 if (!config || ast_string_field_init(config, 256)) {
832 return NULL;
833 }
834
835 return config;
836}
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 817 of file res_pjsip_publish_asterisk.c.

818{
820
822}
#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 490 of file res_pjsip_publish_asterisk.c.

492{
493 const char *device = ast_json_string_get(ast_json_object_get(json, "device"));
494 const char *state = ast_json_string_get(ast_json_object_get(json, "state"));
495 int cachable = ast_json_integer_get(ast_json_object_get(json, "cachable"));
496
497 if (!config->device_state) {
498 ast_debug(2, "Received device state event for resource '%s' but it is not configured to accept them\n",
500 return 0;
501 }
502
503 if (ast_strlen_zero(device) || ast_strlen_zero(state)) {
504 ast_debug(1, "Received incomplete device state event for resource '%s'\n",
506 return -1;
507 }
508
509 if (config->device_state_filter && regexec(&config->device_state_regex, device, 0, NULL, 0)) {
510 ast_debug(2, "Received device state on resource '%s' for device '%s' but it has been filtered out\n",
512 return 0;
513 }
514
517 pubsub_eid);
518
519 return 0;
520}
@ 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:260
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:709
#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:2312
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 557 of file res_pjsip_publish_asterisk.c.

559{
560 struct ast_sip_outbound_publish_client *client;
561 struct ast_datastore *datastore;
562 struct ao2_container *cached;
563
564 if (ast_strlen_zero(config->devicestate_publish)) {
565 return 0;
566 }
567
568 client = ast_sip_publish_client_get(config->devicestate_publish);
569 if (!client) {
570 ast_log(LOG_ERROR, "Received refresh request for devicestate on publication '%s' but publish '%s' is not available\n",
571 ast_sorcery_object_get_id(config), config->devicestate_publish);
572 return 0;
573 }
574
575 datastore = ast_sip_publish_client_get_datastore(client, "asterisk-devicestate-publisher");
576 if (!datastore) {
577 ao2_ref(client, -1);
578 return 0;
579 }
580
582 if (cached) {
583 ao2_callback(cached, OBJ_NODATA, cached_devstate_cb, datastore);
584 ao2_ref(cached, -1);
585 }
586 ao2_ref(client, -1);
587 ao2_ref(datastore, -1);
588
589 return 0;
590}
#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:673
#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 592 of file res_pjsip_publish_asterisk.c.

594{
597 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
598 const char *eid, *type;
599 struct ast_eid pubsub_eid;
600 int res = -1;
601
602 /* If no configuration exists for this publication it has most likely been removed, so drop this immediately */
603 if (!config) {
604 return -1;
605 }
606
607 /* If no body exists this is a refresh and can be ignored */
608 if (!body) {
609 return 0;
610 }
611
612 /* We only accept JSON for content */
613 if (!ast_sip_is_content_type(&body->content_type, "application", "json")) {
614 ast_debug(2, "Received unsupported content type for Asterisk event on resource '%s'\n",
616 return -1;
617 }
618
619 json = ast_json_load_buf(body->data, body->len, NULL);
620 if (!json) {
621 ast_debug(1, "Received unparseable JSON event for resource '%s'\n",
623 return -1;
624 }
625
627 if (!eid) {
628 ast_debug(1, "Received event without eid for resource '%s'\n",
630 return -1;
631 }
632 ast_str_to_eid(&pubsub_eid, eid);
633
635 if (!type) {
636 ast_debug(1, "Received event without type for resource '%s'\n",
638 return -1;
639 } else if (!strcmp(type, "devicestate")) {
640 res = asterisk_publication_devicestate(pub, config, &pubsub_eid, json);
641 } else if (!strcmp(type, "refresh")) {
642 res = asterisk_publication_devicestate_refresh(pub, config, &pubsub_eid, json);
643 }
644
645 return res;
646}
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 522 of file res_pjsip_publish_asterisk.c.

524{
525 const char *uniqueid = ast_json_string_get(ast_json_object_get(json, "uniqueid"));
526 int old_msgs = ast_json_integer_get(ast_json_object_get(json, "old"));
527 int new_msgs = ast_json_integer_get(ast_json_object_get(json, "new"));
528 char *item_id;
529 const char *mailbox;
530
531 if (!config->mailbox_state) {
532 ast_debug(2, "Received mailbox state event for resource '%s' but it is not configured to accept them\n",
534 return 0;
535 }
536
537 if (ast_strlen_zero(uniqueid)) {
538 ast_debug(1, "Received incomplete mailbox state event for resource '%s'\n",
540 return -1;
541 }
542
543 if (config->mailbox_state_filter && regexec(&config->mailbox_state_regex, uniqueid, 0, NULL, 0)) {
544 ast_debug(2, "Received mailbox state on resource '%s' for uniqueid '%s' but it has been filtered out\n",
546 return 0;
547 }
548
549 item_id = ast_strdupa(uniqueid);
550 mailbox = strsep(&item_id, "@");
551
552 ast_publish_mwi_state_full(mailbox, item_id, new_msgs, old_msgs, NULL, pubsub_eid);
553
554 return 0;
555}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * strsep(char **str, const char *delims)
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 648 of file res_pjsip_publish_asterisk.c.

650{
651 struct ast_sip_outbound_publish_client *client;
652 struct ast_datastore *datastore;
653 struct ao2_container *cached;
654
655 if (ast_strlen_zero(config->mailboxstate_publish)) {
656 return 0;
657 }
658
659 client = ast_sip_publish_client_get(config->mailboxstate_publish);
660 if (!client) {
661 ast_log(LOG_ERROR, "Received refresh request for mwi state on publication '%s' but publish '%s' is not available\n",
662 ast_sorcery_object_get_id(config), config->mailboxstate_publish);
663 return 0;
664 }
665
666 datastore = ast_sip_publish_client_get_datastore(client, "asterisk-mwi-publisher");
667 if (!datastore) {
668 ao2_ref(client, -1);
669 return 0;
670 }
671
673 if (cached) {
674 ao2_callback(cached, OBJ_NODATA, cached_mwistate_cb, datastore);
675 ao2_ref(cached, -1);
676 }
677 ao2_ref(client, -1);
678 ao2_ref(datastore, -1);
679
680 return 0;
681}
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 683 of file res_pjsip_publish_asterisk.c.

685{
688 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
689 const char *eid, *type;
690 struct ast_eid pubsub_eid;
691 int res = -1;
692
693 /* If no configuration exists for this publication it has most likely been removed, so drop this immediately */
694 if (!config) {
695 return -1;
696 }
697
698 /* If no body exists this is a refresh and can be ignored */
699 if (!body) {
700 return 0;
701 }
702
703 /* We only accept JSON for content */
704 if (!ast_sip_is_content_type(&body->content_type, "application", "json")) {
705 ast_debug(2, "Received unsupported content type for Asterisk event on resource '%s'\n",
707 return -1;
708 }
709
710 json = ast_json_load_buf(body->data, body->len, NULL);
711 if (!json) {
712 ast_debug(1, "Received unparseable JSON event for resource '%s'\n",
714 return -1;
715 }
716
718 if (!eid) {
719 ast_debug(1, "Received event without eid for resource '%s'\n",
721 return -1;
722 }
723 ast_str_to_eid(&pubsub_eid, eid);
724
726 if (!type) {
727 ast_debug(1, "Received event without type for resource '%s'\n",
729 return -1;
730 } else if (!strcmp(type, "mailboxstate")) {
731 res = asterisk_publication_mailboxstate(pub, config, &pubsub_eid, json);
732 } else if (!strcmp(type, "refresh")) {
733 res = asterisk_publication_mwi_refresh(pub, config, &pubsub_eid, json);
734 }
735
736 return res;
737}
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 477 of file res_pjsip_publish_asterisk.c.

478{
480 event_configuration), ao2_cleanup);
481
482 /* If no inbound Asterisk publication configuration exists reject the PUBLISH */
483 if (!config) {
484 return 404;
485 }
486
487 return 200;
488}

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 764 of file res_pjsip_publish_asterisk.c.

765{
767 char eid_str[20];
768 struct ast_json *json;
769 char *text;
770 struct ast_sip_body body = {
771 .type = "application",
772 .subtype = "json",
773 };
774
775 if (!publications) {
776 return;
777 }
778
779 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
780 json = ast_json_pack(
781 "{ s: s, s: s }",
782 "type", "refresh",
783 "eid", eid_str);
784 if (!json) {
785 ao2_ref(publications, -1);
786 return;
787 }
788
790 if (!text) {
791 ast_json_unref(json);
792 ao2_ref(publications, -1);
793 return;
794 }
795 body.body_text = text;
796
797 ao2_callback(publications, OBJ_NODATA, send_refresh_cb, &body);
798
800 ast_json_unref(json);
801 ao2_ref(publications, -1);
802}
char * text
Definition: app_queue.c:1639
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:2313
const char * type
Definition: res_pjsip.h:2315
const char * body_text
Definition: res_pjsip.h:2319
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:93

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 172 of file res_pjsip_publish_asterisk.c.

173{
174 struct ast_datastore *datastore = data;
175 struct asterisk_devicestate_publisher_state *publisher_state = datastore->data;
176 struct ast_device_state_message *dev_state;
177 char eid_str[20];
178 struct ast_json *json;
179 char *text;
180 struct ast_sip_body body = {
181 .type = "application",
182 .subtype = "json",
183 };
184
186 return;
187 }
188
189 dev_state = stasis_message_data(msg);
190 if (!dev_state->eid || ast_eid_cmp(&ast_eid_default, dev_state->eid)) {
191 /* If the event is aggregate or didn't originate from this server, don't send it out. */
192 return;
193 }
194
195 if (publisher_state->device_state_filter && regexec(&publisher_state->device_state_regex, dev_state->device, 0, NULL, 0)) {
196 /* Outgoing device state has been filtered and the device name does not match */
197 return;
198 }
199
200 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
201 json = ast_json_pack(
202 "{ s: s, s: s, s: s, s: i, s:s }",
203 "type", "devicestate",
204 "device", dev_state->device,
205 "state", ast_devstate_str(dev_state->state),
206 "cachable", dev_state->cachable,
207 "eid", eid_str);
208 if (!json) {
209 return;
210 }
211
213 if (!text) {
214 ast_json_unref(json);
215 return;
216 }
217 body.body_text = text;
218
219 ast_sip_publish_client_send(publisher_state->client, &body);
220
222 ast_json_unref(json);
223}
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:255
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:1150
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 230 of file res_pjsip_publish_asterisk.c.

231{
232 struct ast_datastore *datastore = data;
233 struct asterisk_mwi_publisher_state *publisher_state = datastore->data;
234 struct ast_mwi_state *mwi_state;
235 char eid_str[20];
236 struct ast_json *json;
237 char *text;
238 struct ast_sip_body body = {
239 .type = "application",
240 .subtype = "json",
241 };
242
244 return;
245 }
246
247 mwi_state = stasis_message_data(msg);
248 if (ast_eid_cmp(&ast_eid_default, &mwi_state->eid)) {
249 /* If the event is aggregate or didn't originate from this server, don't send it out. */
250 return;
251 }
252
253 if (publisher_state->mailbox_state_filter && regexec(&publisher_state->mailbox_state_regex, mwi_state->uniqueid, 0, NULL, 0)) {
254 /* Outgoing mailbox state has been filtered and the uniqueid does not match */
255 return;
256 }
257
258 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
259 json = ast_json_pack(
260 "{ s: s, s: s, s: i, s: i, s:s }",
261 "type", "mailboxstate",
262 "uniqueid", mwi_state->uniqueid,
263 "old", mwi_state->old_msgs,
264 "new", mwi_state->new_msgs,
265 "eid", eid_str);
266 if (!json) {
267 return;
268 }
269
271 if (!text) {
272 ast_json_unref(json);
273 return;
274 }
275 body.body_text = text;
276
277 ast_sip_publish_client_send(publisher_state->client, &body);
278
280 ast_json_unref(json);
281}
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 320 of file res_pjsip_publish_asterisk.c.

322{
323 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
324 struct asterisk_devicestate_publisher_state *publisher_state;
325 const char *value;
326 struct ao2_container *cached;
327
329 "asterisk-devicestate-publisher");
330 if (!datastore) {
331 return -1;
332 }
333
334 publisher_state = ast_calloc(1, sizeof(struct asterisk_devicestate_publisher_state));
335 if (!publisher_state) {
336 return -1;
337 }
338 datastore->data = publisher_state;
339
340 value = ast_sorcery_object_get_extended(configuration, "device_state_filter");
341 if (!ast_strlen_zero(value)) {
342 if (build_regex(&publisher_state->device_state_regex, value)) {
343 return -1;
344 }
345 publisher_state->device_state_filter = 1;
346 }
347
348 publisher_state->client = ao2_bump(client);
349
350 if (ast_sip_publish_client_add_datastore(client, datastore)) {
351 return -1;
352 }
353
356 if (!publisher_state->device_state_subscription) {
357 ast_sip_publish_client_remove_datastore(client, "asterisk-devicestate-publisher");
358 ao2_ref(datastore, -1);
359 return -1;
360 }
364
366 ao2_callback(cached, OBJ_NODATA, cached_devstate_cb, datastore);
367 ao2_ref(cached, -1);
368
369 return 0;
370}
#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:668
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:2330
@ 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:1023
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:1077
#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 399 of file res_pjsip_publish_asterisk.c.

401{
402 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
403 struct asterisk_mwi_publisher_state *publisher_state;
404 const char *value;
405 struct ao2_container *cached;
406
408 if (!datastore) {
409 return -1;
410 }
411
412 publisher_state = ast_calloc(1, sizeof(struct asterisk_mwi_publisher_state));
413 if (!publisher_state) {
414 return -1;
415 }
416 datastore->data = publisher_state;
417
418 value = ast_sorcery_object_get_extended(configuration, "mailbox_state_filter");
419 if (!ast_strlen_zero(value)) {
420 if (build_regex(&publisher_state->mailbox_state_regex, value)) {
421 return -1;
422 }
423 publisher_state->mailbox_state_filter = 1;
424 }
425
426 publisher_state->client = ao2_bump(client);
427
428 if (ast_sip_publish_client_add_datastore(client, datastore)) {
429 return -1;
430 }
431
434 if (!publisher_state->mailbox_state_subscription) {
435 ast_sip_publish_client_remove_datastore(client, "asterisk-mwi-publisher");
436 ao2_ref(datastore, -1);
437 return -1;
438 }
442
444 ao2_callback(cached, OBJ_NODATA, cached_mwistate_cb, datastore);
445 ao2_ref(cached, -1);
446
447 return 0;
448}
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 372 of file res_pjsip_publish_asterisk.c.

373{
374 RAII_VAR(struct ast_datastore *, datastore, ast_sip_publish_client_get_datastore(client, "asterisk-devicestate-publisher"),
376 struct asterisk_devicestate_publisher_state *publisher_state;
377
378 if (!datastore) {
379 return 0;
380 }
381
382 publisher_state = datastore->data;
383 if (publisher_state->device_state_subscription) {
385 ao2_ref(datastore, -1);
386 }
387
388 ast_sip_publish_client_remove_datastore(client, "asterisk-devicestate-publisher");
389
390 return 0;
391}
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134

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 450 of file res_pjsip_publish_asterisk.c.

451{
452 RAII_VAR(struct ast_datastore *, datastore, ast_sip_publish_client_get_datastore(client, "asterisk-mwi-publisher"),
454 struct asterisk_mwi_publisher_state *publisher_state;
455
456 if (!datastore) {
457 return 0;
458 }
459
460 publisher_state = datastore->data;
461 if (publisher_state->mailbox_state_subscription) {
463 ao2_ref(datastore, -1);
464 }
465
466 ast_sip_publish_client_remove_datastore(client, "asterisk-mwi-publisher");
467
468 return 0;
469}

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 305 of file res_pjsip_publish_asterisk.c.

306{
307 int res;
308
309 if ((res = regcomp(regex, text, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
310 size_t len = regerror(res, regex, NULL, 0);
311 char buf[len];
312 regerror(res, regex, buf, len);
313 ast_log(LOG_ERROR, "Could not compile regex '%s': %s\n", text, buf);
314 return -1;
315 }
316
317 return 0;
318}
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 294 of file res_pjsip_publish_asterisk.c.

295{
296 struct stasis_message *msg = obj;
297 struct ast_datastore *datastore = arg;
298 struct asterisk_mwi_publisher_state *publisher_state = datastore->data;
299
301
302 return 0;
303}

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 860 of file res_pjsip_publish_asterisk.c.

861{
863 ast_log(LOG_ERROR, "Entity ID is not set.\n");
865 }
866
867 ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_publish_asterisk");
868 ast_sorcery_apply_default(ast_sip_get_sorcery(), "asterisk-publication", "config", "pjsip.conf,criteria=type=asterisk-publication");
869
871 ast_log(LOG_ERROR, "Unable to register 'asterisk-publication' type with sorcery\n");
873 }
874
875 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "type", "", OPT_NOOP_T, 0, 0);
876 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "devicestate_publish", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct asterisk_publication_config, devicestate_publish));
877 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "asterisk-publication", "mailboxstate_publish", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct asterisk_publication_config, mailboxstate_publish));
878 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));
879 ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "asterisk-publication", "device_state_filter", "", regex_filter_handler, NULL, NULL, 0, 0);
880 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));
881 ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "asterisk-publication", "mailbox_state_filter", "", regex_filter_handler, NULL, NULL, 0, 0);
882 ast_sorcery_reload_object(ast_sip_get_sorcery(), "asterisk-publication");
883
885 ast_log(LOG_WARNING, "Unable to register event publication handler %s\n",
888 }
890 ast_log(LOG_WARNING, "Unable to register event publication handler %s\n",
894 }
896 ast_log(LOG_WARNING, "Unable to register event publisher handler %s\n",
901 }
903 ast_log(LOG_WARNING, "Unable to register event publisher handler %s\n",
909 }
910
912
914}
#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 838 of file res_pjsip_publish_asterisk.c.

839{
841 int res = -1;
842
843 if (ast_strlen_zero(var->value)) {
844 return 0;
845 }
846
847 if (!strcmp(var->name, "device_state_filter")) {
848 if (!(res = build_regex(&config->device_state_regex, var->value))) {
849 config->device_state_filter = 1;
850 }
851 } else if (!strcmp(var->name, "mailbox_state_filter")) {
852 if (!(res = build_regex(&config->mailbox_state_regex, var->value))) {
853 config->mailbox_state_filter = 1;
854 }
855 }
856
857 return res;
858}
#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 739 of file res_pjsip_publish_asterisk.c.

740{
742 struct ast_sip_outbound_publish_client *client;
743
744 if (!ast_strlen_zero(config->devicestate_publish)) {
745 client = ast_sip_publish_client_get(config->devicestate_publish);
746 if (client) {
747 ast_sip_publish_client_send(client, arg);
748 ao2_ref(client, -1);
749 }
750 }
751
752 if (!ast_strlen_zero(config->mailboxstate_publish)) {
753 client = ast_sip_publish_client_get(config->mailboxstate_publish);
754 if (client) {
755 ast_sip_publish_client_send(client, arg);
756 ao2_ref(client, -1);
757 }
758 }
759
760 return 0;
761}

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 940 of file res_pjsip_publish_asterisk.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 940 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 804 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 393 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 144 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 810 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 471 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 162 of file res_pjsip_publish_asterisk.c.

Referenced by asterisk_start_mwi_publishing().