32#include <pjsip_simple.h>
145 .
type =
"asterisk-devicestate-publisher",
163 .
type =
"asterisk-mwi-publisher",
181 .
type =
"application",
202 "{ s: s, s: s, s: s, s: i, s:s }",
203 "type",
"devicestate",
204 "device", dev_state->
device,
239 .
type =
"application",
260 "{ s: s, s: s, s: i, s: i, s:s }",
261 "type",
"mailboxstate",
309 if ((res = regcomp(
regex,
text, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
329 "asterisk-devicestate-publisher");
335 if (!publisher_state) {
338 datastore->data = publisher_state;
382 publisher_state = datastore->data;
413 if (!publisher_state) {
416 datastore->data = publisher_state;
460 publisher_state = datastore->data;
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",
504 ast_debug(1,
"Received incomplete device state event for resource '%s'\n",
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",
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",
538 ast_debug(1,
"Received incomplete mailbox state event for resource '%s'\n",
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",
570 ast_log(
LOG_ERROR,
"Received refresh request for devicestate on publication '%s' but publish '%s' is not available\n",
598 const char *eid, *
type;
614 ast_debug(2,
"Received unsupported content type for Asterisk event on resource '%s'\n",
621 ast_debug(1,
"Received unparseable JSON event for resource '%s'\n",
628 ast_debug(1,
"Received event without eid for resource '%s'\n",
636 ast_debug(1,
"Received event without type for resource '%s'\n",
639 }
else if (!strcmp(
type,
"devicestate")) {
641 }
else if (!strcmp(
type,
"refresh")) {
661 ast_log(
LOG_ERROR,
"Received refresh request for mwi state on publication '%s' but publish '%s' is not available\n",
689 const char *eid, *
type;
705 ast_debug(2,
"Received unsupported content type for Asterisk event on resource '%s'\n",
712 ast_debug(1,
"Received unparseable JSON event for resource '%s'\n",
719 ast_debug(1,
"Received event without eid for resource '%s'\n",
727 ast_debug(1,
"Received event without type for resource '%s'\n",
730 }
else if (!strcmp(
type,
"mailboxstate")) {
732 }
else if (!strcmp(
type,
"refresh")) {
771 .
type =
"application",
847 if (!strcmp(
var->name,
"device_state_filter")) {
849 config->device_state_filter = 1;
851 }
else if (!strcmp(
var->name,
"mailbox_state_filter")) {
853 config->mailbox_state_filter = 1;
871 ast_log(
LOG_ERROR,
"Unable to register 'asterisk-publication' type with sorcery\n");
939 .
requires =
"res_pjsip,res_pjsip_outbound_publish,res_pjsip_pubsub",
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
static const char config[]
#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.
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
@ AST_DEVSTATE_NOT_CACHABLE
const char * ast_devstate_str(enum ast_device_state devstate) attribute_pure
Convert device state to text string that is easier to parse.
struct stasis_cache * ast_device_state_cache(void)
Backend cache for ast_device_state_topic_cached()
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
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.
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)
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
char * strsep(char **str, const char *delims)
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
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.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
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.
struct stasis_topic * ast_mwi_topic_all(void)
Get the Stasis Message Bus API topic for MWI messages.
struct stasis_forward * sub
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.
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.
void ast_sip_unregister_event_publisher_handler(struct ast_sip_event_publisher_handler *handler)
Unregister a publish handler.
struct ast_datastore * ast_sip_publish_client_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
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.
int ast_sip_register_event_publisher_handler(struct ast_sip_event_publisher_handler *handler)
Register an event publisher handler.
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.
struct ast_sip_publish_handler asterisk_devicestate_publication_handler
struct ast_sip_event_publisher_handler asterisk_mwi_publisher_handler
static void asterisk_publication_config_destroy(void *obj)
Destructor function for Asterisk publication configuration.
static void asterisk_devicestate_publisher_state_destroy(void *obj)
Destroy callback for Asterisk devicestate publisher state information from datastore.
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_stop_devicestate_publishing(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 void asterisk_publisher_mwistate_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Callback function for mailbox state events.
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_stop_mwi_publishing(struct ast_sip_outbound_publish_client *client)
static void asterisk_publisher_devstate_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Callback function for device state events.
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)
static int reload_module(void)
static int asterisk_start_devicestate_publishing(struct ast_sip_outbound_publish *configuration, struct ast_sip_outbound_publish_client *client)
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 cached_devstate_cb(void *obj, void *arg, int flags)
static int cached_mwistate_cb(void *obj, void *arg, int flags)
static int build_regex(regex_t *regex, const char *text)
struct ast_sip_event_publisher_handler asterisk_devicestate_publisher_handler
static int load_module(void)
static int asterisk_publication_devicestate_state_change(struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)
static int unload_module(void)
static int asterisk_publication_new(struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration)
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 const struct ast_datastore_info asterisk_devicestate_publisher_state_datastore
Datastore for attaching devicestate publisher state information.
static const struct ast_datastore_info asterisk_mwi_publisher_state_datastore
Datastore for attaching devicestate publisher state information.
static int send_refresh_cb(void *obj, void *arg, int flags)
struct ast_sip_publish_handler asterisk_mwi_publication_handler
static void asterisk_mwi_publisher_state_destroy(void *obj)
Destroy callback for Asterisk mwi publisher state information from datastore.
static int asterisk_publication_mwi_state_change(struct ast_sip_publication *pub, pjsip_msg_body *body, enum ast_sip_publish_state state)
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.
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.
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
#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.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
#define ast_sorcery_apply_config(sorcery, name)
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
#define ast_sorcery_apply_default(sorcery, type, name, data)
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
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.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
int stasis_subscription_is_subscribed(const struct stasis_subscription *sub)
Returns whether a subscription is currently subscribed.
#define stasis_subscribe(topic, callback, data)
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Structure for a data store type.
Structure for a data store object.
The structure that contains device state.
enum ast_device_state state
const struct ast_eid * eid
The EID of the server where this message originated.
enum ast_devstate_cache cachable
An Entity ID is essentially a MAC address, brief and unique.
Abstract JSON element (object, array, string, int, ...).
The structure that contains MWI state.
const ast_string_field uniqueid
An entity with which Asterisk communicates.
Callbacks that event publisher handlers will define.
const char * event_name
The name of the event this handler deals with.
Outbound publish client state information (persists for lifetime of a publish)
Outbound publish information.
Structure representing a SIP publication.
Callbacks that publication handlers will define.
const char * event_name
The name of the event this handler deals with.
Structure for variables, used for configurations and for channel variables.
Structure which contains Asterisk device state publisher state information.
regex_t device_state_regex
Regex used for filtering outbound device state.
struct stasis_subscription * device_state_subscription
Device state subscription.
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.
Structure which contains Asterisk mailbox publisher state information.
struct stasis_subscription * mailbox_state_subscription
Mailbox state subscription.
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.
Structure which contains Asterisk publication information.
SORCERY_OBJECT(details)
Sorcery object details.
regex_t device_state_regex
Regex used for filtering inbound device state.
regex_t mailbox_state_regex
Regex used for filtering inbound mailbox state.
const ast_string_field mailboxstate_publish
unsigned int mailbox_state_filter
Mailbox state should be filtered.
unsigned int mailbox_state
Accept inbound mailbox state events.
unsigned int device_state
Accept inbound device state events.
const ast_string_field devicestate_publish
unsigned int device_state_filter
Device state should be filtered.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
struct ast_eid ast_eid_default
Global EID.
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.