[asterisk-commits] marquis: branch group/pinana-publish-1.4 r284279 - /team/group/pinana-publish...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 30 16:55:46 CDT 2010
Author: marquis
Date: Mon Aug 30 16:55:28 2010
New Revision: 284279
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=284279
Log:
Initial backport of the Event Publication Agent (EPA) from trunk.
Modified:
team/group/pinana-publish-1.4/channels/chan_sip.c
Modified: team/group/pinana-publish-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/channels/chan_sip.c?view=diff&rev=284279&r1=284278&r2=284279
==============================================================================
--- team/group/pinana-publish-1.4/channels/chan_sip.c (original)
+++ team/group/pinana-publish-1.4/channels/chan_sip.c Mon Aug 30 16:55:28 2010
@@ -299,6 +299,57 @@
MWI_NOTIFICATION
};
+/*!
+ * \brief The types of PUBLISH messages defined in RFC 3903
+ */
+enum sip_publish_type {
+ /*!
+ * \brief Unknown
+ *
+ * \details
+ * This actually is not defined in RFC 3903. We use this as a constant
+ * to indicate that an incoming PUBLISH does not fit into any of the
+ * other categories and is thus invalid.
+ */
+ SIP_PUBLISH_UNKNOWN,
+ /*!
+ * \brief Initial
+ *
+ * \details
+ * The first PUBLISH sent. This will contain a non-zero Expires header
+ * as well as a body that indicates the current state of the endpoint
+ * that has sent the message. The initial PUBLISH is the only type
+ * of PUBLISH to not contain a Sip-If-Match header in it.
+ */
+ SIP_PUBLISH_INITIAL,
+ /*!
+ * \brief Refresh
+ *
+ * \details
+ * Used to keep a published state from expiring. This will contain a
+ * non-zero Expires header but no body since its purpose is not to
+ * update state.
+ */
+ SIP_PUBLISH_REFRESH,
+ /*!
+ * \brief Modify
+ *
+ * \details
+ * Used to change state from its previous value. This will contain
+ * a body updating the published state. May or may not contain an
+ * Expires header.
+ */
+ SIP_PUBLISH_MODIFY,
+ /*!
+ * \brief Remove
+ *
+ * \details
+ * Used to remove published state from an ESC. This will contain
+ * an Expires header set to 0 and likely no body.
+ */
+ SIP_PUBLISH_REMOVE,
+};
+
static const struct cfsubscription_types {
enum subscriptiontype type;
const char * const event;
@@ -480,7 +531,7 @@
/*! \brief SIP Methods we support */
-#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO"
+#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH"
/*! \brief SIP Extensions we support */
#define SUPPORTED_EXTENSIONS "replaces"
@@ -1080,6 +1131,79 @@
#define FLAG_RESPONSE (1 << 0)
#define FLAG_FATAL (1 << 1)
+struct sip_epa_entry {
+ /*!
+ * When we are going to send a publish, we need to
+ * know the type of PUBLISH to send.
+ */
+ enum sip_publish_type publish_type;
+ /*!
+ * When we send a PUBLISH, we have to be
+ * sure to include the entity tag that we
+ * received in the previous response.
+ */
+ char entity_tag[SIPBUFSIZE];
+ /*!
+ * The destination to which this EPA should send
+ * PUBLISHes. This may be the name of a SIP peer
+ * or a hostname.
+ */
+ char destination[SIPBUFSIZE];
+ /*!
+ * The body of the most recently-sent PUBLISH message.
+ * This is useful for situations such as authentication,
+ * in which we must send a message identical to the
+ * one previously sent
+ */
+ char body[SIPBUFSIZE];
+ /*!
+ * Every event package has some constant data and
+ * callbacks that all instances will share. This
+ * data resides in this field.
+ */
+ const struct epa_static_data *static_data;
+ /*!
+ * In addition to the static data that all instances
+ * of sip_epa_entry will have, each instance will
+ * require its own instance-specific data.
+ */
+ void *instance_data;
+};
+
+/*!
+ * Data which is the same for all instances of an EPA for a
+ * particular event package
+ */
+struct epa_static_data {
+ /*! The event type */
+ enum subscriptiontype event;
+ /*!
+ * The name of the event as it would
+ * appear in a SIP message
+ */
+ const char *name;
+ /*!
+ * The callback called when a 200 OK is received on an outbound PUBLISH
+ */
+ void (*handle_ok)(struct sip_pvt *, struct sip_request *, struct sip_epa_entry *);
+ /*!
+ * The callback called when an error response is received on an outbound PUBLISH
+ */
+ void (*handle_error)(struct sip_pvt *, const int resp, struct sip_request *, struct sip_epa_entry *);
+ /*!
+ * Destructor to call to clean up instance data
+ */
+ void (*destructor)(void *instance_data);
+};
+
+/*!
+ * \brief backend for an event publication agent
+ */
+struct epa_backend {
+ const struct epa_static_data *static_data;
+ AST_LIST_ENTRY(epa_backend) next;
+};
+
/*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission */
struct sip_pkt {
struct sip_pkt *next; /*!< Next packet in linked list */
@@ -1692,6 +1816,56 @@
get_udptl_info: sip_get_udptl_peer,
set_udptl_peer: sip_set_udptl_peer,
};
+
+AST_LIST_HEAD_STATIC(epa_static_data_list, epa_backend);
+
+static int sip_epa_register(const struct epa_static_data *static_data)
+{
+ struct epa_backend *backend = ast_calloc(1, sizeof(*backend));
+
+ if (!backend) {
+ return -1;
+ }
+
+ backend->static_data = static_data;
+
+ AST_LIST_LOCK(&epa_static_data_list);
+ AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next);
+ AST_LIST_UNLOCK(&epa_static_data_list);
+ return 0;
+}
+
+static const struct epa_static_data *find_static_data(const char * const event_package)
+{
+ const struct epa_backend *backend = NULL;
+
+ AST_LIST_LOCK(&epa_static_data_list);
+ AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) {
+ if (!strcmp(backend->static_data->name, event_package)) {
+ break;
+ }
+ }
+ AST_LIST_UNLOCK(&epa_static_data_list);
+ return backend ? backend->static_data : NULL;
+}
+
+static struct sip_epa_entry *create_epa_entry (const char * const event_package, const char * const destination)
+{
+ struct sip_epa_entry *epa_entry;
+ const struct epa_static_data *static_data;
+
+ if (!(static_data = find_static_data(event_package))) {
+ return NULL;
+ }
+
+ if (!(epa_entry = ao2_alloc(sizeof(*epa_entry), static_data->destructor))) {
+ return NULL;
+ }
+
+ epa_entry->static_data = static_data;
+ ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination));
+ return epa_entry;
+}
/*! \brief Convert transfer status to string */
static char *referstatus2str(enum referstatus rstatus)
More information about the asterisk-commits
mailing list