[asterisk-commits] mjordan: branch mjordan/12-messaging r418441 - in /team/mjordan/12-messaging:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Jul 12 11:28:00 CDT 2014
Author: mjordan
Date: Sat Jul 12 11:27:56 2014
New Revision: 418441
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=418441
Log:
Add initial stuff
Added:
team/mjordan/12-messaging/tests/test_message.c (with props)
Modified:
team/mjordan/12-messaging/channels/chan_iax2.c
team/mjordan/12-messaging/channels/chan_motif.c
team/mjordan/12-messaging/channels/chan_pjsip.c
team/mjordan/12-messaging/channels/chan_sip.c
team/mjordan/12-messaging/include/asterisk/channel.h
team/mjordan/12-messaging/include/asterisk/endpoints.h
team/mjordan/12-messaging/include/asterisk/json.h
team/mjordan/12-messaging/include/asterisk/manager.h
team/mjordan/12-messaging/include/asterisk/message.h
team/mjordan/12-messaging/include/asterisk/vector.h
team/mjordan/12-messaging/include/asterisk/xmpp.h
team/mjordan/12-messaging/main/channel.c
team/mjordan/12-messaging/main/channel_internal_api.c
team/mjordan/12-messaging/main/endpoints.c
team/mjordan/12-messaging/main/json.c
team/mjordan/12-messaging/main/message.c
team/mjordan/12-messaging/res/ari/ari_model_validators.c
team/mjordan/12-messaging/res/ari/ari_model_validators.h
team/mjordan/12-messaging/res/ari/resource_applications.h
team/mjordan/12-messaging/res/ari/resource_channels.c
team/mjordan/12-messaging/res/ari/resource_endpoints.c
team/mjordan/12-messaging/res/ari/resource_endpoints.h
team/mjordan/12-messaging/res/res_ari.c
team/mjordan/12-messaging/res/res_ari_endpoints.c
team/mjordan/12-messaging/res/res_pjsip_messaging.c
team/mjordan/12-messaging/res/res_stasis.c
team/mjordan/12-messaging/res/res_xmpp.c
team/mjordan/12-messaging/res/stasis/app.c
team/mjordan/12-messaging/rest-api/api-docs/applications.json
team/mjordan/12-messaging/rest-api/api-docs/endpoints.json
team/mjordan/12-messaging/rest-api/api-docs/events.json
Modified: team/mjordan/12-messaging/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/channels/chan_iax2.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/channels/chan_iax2.c (original)
+++ team/mjordan/12-messaging/channels/chan_iax2.c Sat Jul 12 11:27:56 2014
@@ -5777,20 +5777,38 @@
/*! \brief Create new call, interface with the PBX core */
static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, unsigned int cachable)
{
- struct ast_channel *tmp;
+ struct ast_channel *tmp = NULL;
struct chan_iax2_pvt *i;
+ struct iax2_peer *peer;
struct ast_variable *v = NULL;
struct ast_format tmpfmt;
struct ast_callid *callid;
+ char *peer_name = NULL;
if (!(i = iaxs[callno])) {
ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
return NULL;
}
- /* Don't hold call lock */
+ if (!ast_strlen_zero(i->peer)) {
+ peer_name = ast_strdupa(i->peer);
+ }
+
+ /* Don't hold call lock while making a channel or looking up a peer */
ast_mutex_unlock(&iaxsl[callno]);
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
+
+ if (!ast_strlen_zero(peer_name)) {
+ peer = find_peer(peer_name, 1);
+ if (peer && peer->endpoint) {
+ tmp = ast_channel_alloc_with_endpoint(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, peer->endpoint, "IAX2/%s-%d", i->host, i->callno);
+ }
+ ao2_cleanup(peer);
+ }
+
+ if (!tmp) {
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
+ }
+
ast_mutex_lock(&iaxsl[callno]);
if (i != iaxs[callno]) {
if (tmp) {
Modified: team/mjordan/12-messaging/channels/chan_motif.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/channels/chan_motif.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/channels/chan_motif.c (original)
+++ team/mjordan/12-messaging/channels/chan_motif.c Sat Jul 12 11:27:56 2014
@@ -76,6 +76,7 @@
#include "asterisk/astobj.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/xmpp.h"
+#include "asterisk/endpoints.h"
#include "asterisk/stasis_channels.h"
/*** DOCUMENTATION
@@ -782,7 +783,7 @@
return NULL;
}
- if (!(chan = ast_channel_alloc(1, state, S_OR(title, ""), S_OR(cid_name, ""), "", "", "", assignedids, requestor, 0, "Motif/%s-%04lx", str, (unsigned long)(ast_random() & 0xffff)))) {
+ if (!(chan = ast_channel_alloc_with_endpoint(1, state, S_OR(title, ""), S_OR(cid_name, ""), "", "", "", assignedids, requestor, 0, endpoint->connection->endpoint, "Motif/%s-%04lx", str, (unsigned long)(ast_random() & 0xffff)))) {
return NULL;
}
Modified: team/mjordan/12-messaging/channels/chan_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/channels/chan_pjsip.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/channels/chan_pjsip.c (original)
+++ team/mjordan/12-messaging/channels/chan_pjsip.c Sat Jul 12 11:27:56 2014
@@ -364,7 +364,7 @@
return NULL;
}
- if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", assignedids, requestor, 0, "PJSIP/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
+ if (!(chan = ast_channel_alloc_with_endpoint(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", assignedids, requestor, 0, session->endpoint->persistent, "PJSIP/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
(unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1)))) {
return NULL;
}
@@ -441,8 +441,6 @@
if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) {
ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(chan));
}
-
- ast_endpoint_add_channel(session->endpoint->persistent, chan);
return chan;
}
Modified: team/mjordan/12-messaging/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/channels/chan_sip.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/channels/chan_sip.c (original)
+++ team/mjordan/12-messaging/channels/chan_sip.c Sat Jul 12 11:27:56 2014
@@ -8079,23 +8079,19 @@
my_name = ast_strdupa(i->fromdomain);
}
+ /* Don't hold a sip pvt lock while we allocate a channel */
sip_pvt_unlock(i);
- /* Don't hold a sip pvt lock while we allocate a channel */
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
+
+ if (i->relatedpeer && i->relatedpeer->endpoint) {
+ tmp = ast_channel_alloc_with_endpoint(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, i->relatedpeer->endpoint, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
+ } else {
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "SIP/%s-%08x", my_name, (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
+ }
}
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
sip_pvt_lock(i);
return NULL;
- }
-
- if (i->relatedpeer && i->relatedpeer->endpoint) {
- if (ast_endpoint_add_channel(i->relatedpeer->endpoint, tmp)) {
- ast_channel_unlock(tmp);
- ast_channel_unref(tmp);
- sip_pvt_lock(i);
- return NULL;
- }
}
ast_channel_stage_snapshot(tmp);
@@ -19139,25 +19135,6 @@
ast_string_field_set(p, context, sip_cfg.messagecontext);
}
- switch (get_destination(p, NULL, NULL)) {
- case SIP_GET_DEST_REFUSED:
- /* Okay to send 403 since this is after auth processing */
- transmit_response(p, "403 Forbidden", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- case SIP_GET_DEST_INVALID_URI:
- transmit_response(p, "416 Unsupported URI Scheme", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- case SIP_GET_DEST_EXTEN_NOT_FOUND:
- case SIP_GET_DEST_EXTEN_MATCHMORE:
- transmit_response(p, "404 Not Found", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- case SIP_GET_DEST_EXTEN_FOUND:
- break;
- }
-
if (!(msg = ast_msg_alloc())) {
transmit_response(p, "500 Internal Server Error", req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -19182,7 +19159,9 @@
res |= ast_msg_set_context(msg, "%s", p->context);
res |= ast_msg_set_var(msg, "SIP_RECVADDR", ast_sockaddr_stringify(&p->recv));
+ res |= ast_msg_set_tech(msg, "%s", "SIP");
if (!ast_strlen_zero(p->peername)) {
+ res |= ast_msg_set_endpoint(msg, "%s", p->peername);
res |= ast_msg_set_var(msg, "SIP_PEERNAME", p->peername);
}
@@ -19195,12 +19174,38 @@
if (res) {
ast_msg_destroy(msg);
transmit_response(p, "500 Internal Server Error", req);
- } else {
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ return;
+ }
+
+ if (ast_msg_has_destination(msg)) {
ast_msg_queue(msg);
transmit_response(p, "202 Accepted", req);
- }
-
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ return;
+ }
+
+ /* Find a specific error cause to send */
+ switch (get_destination(p, NULL, NULL)) {
+ case SIP_GET_DEST_REFUSED:
+ /* Okay to send 403 since this is after auth processing */
+ transmit_response(p, "403 Forbidden", req);
+ break;
+ case SIP_GET_DEST_INVALID_URI:
+ transmit_response(p, "416 Unsupported URI Scheme", req);
+ break;
+ case SIP_GET_DEST_EXTEN_NOT_FOUND:
+ case SIP_GET_DEST_EXTEN_MATCHMORE:
+ transmit_response(p, "404 Not Found", req);
+ break;
+ case SIP_GET_DEST_EXTEN_FOUND:
+ /* We should have sent the message already! */
+ ast_assert(0);
+ transmit_response(p, "500 Internal Server Error", req);
+ break;
+ }
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ ast_msg_destroy(msg);
}
/*! \brief CLI Command to show calls within limits set by call_limit */
Modified: team/mjordan/12-messaging/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/channel.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/channel.h (original)
+++ team/mjordan/12-messaging/include/asterisk/channel.h Sat Jul 12 11:27:56 2014
@@ -1158,11 +1158,12 @@
* and "default" context.
* \note Since 12.0.0 this function returns with the newly created channel locked.
*/
-struct ast_channel * attribute_malloc __attribute__((format(printf, 14, 15)))
+struct ast_channel * attribute_malloc __attribute__((format(printf, 15, 16)))
__ast_channel_alloc(int needqueue, int state, const char *cid_num,
const char *cid_name, const char *acctcode,
const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
const struct ast_channel *requestor, enum ama_flags amaflag,
+ struct ast_endpoint *endpoint,
const char *file, int line, const char *function,
const char *name_fmt, ...);
@@ -1178,8 +1179,13 @@
* \note Since 12.0.0 this function returns with the newly created channel locked.
*/
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, ...) \
- __ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, \
+ __ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, NULL, \
__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
+
+#define ast_channel_alloc_with_endpoint(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint, ...) \
+ __ast_channel_alloc((needqueue), (state), (cid_num), (cid_name), (acctcode), (exten), (context), (assignedids), (requestor), (amaflag), (endpoint), \
+ __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
+
#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
/*!
Modified: team/mjordan/12-messaging/include/asterisk/endpoints.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/endpoints.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/endpoints.h (original)
+++ team/mjordan/12-messaging/include/asterisk/endpoints.h Sat Jul 12 11:27:56 2014
@@ -77,11 +77,17 @@
struct ast_endpoint;
/*!
- * \brief Finds the endpoint with the given tech/resource id.
+ * \brief Finds the endpoint with the given tech[/resource] id.
*
* Endpoints are refcounted, so ao2_cleanup() when you're done.
*
- * \param id Tech/resource id to look for.
+ * \note The resource portion of an ID is optional. If not provided,
+ * an aggregate endpoint for the entire technology is returned.
+ * These endpoints must not be modified, but can be subscribed
+ * to in order to receive updates for all endpoints of a given
+ * technology.
+ *
+ * \param id Tech[/resource] id to look for.
* \return Associated endpoint.
* \return \c NULL if not found.
*
@@ -131,6 +137,9 @@
*
* This is unique for the endpoint's technology, and immutable.
*
+ * \note If the endpoint being queried is a technology aggregate
+ * endpoint, this will be an empty string.
+ *
* \param endpoint The endpoint.
* \return Resource name of the endpoint.
* \return \c NULL if endpoint is \c NULL.
Modified: team/mjordan/12-messaging/include/asterisk/json.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/json.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/json.h (original)
+++ team/mjordan/12-messaging/include/asterisk/json.h Sat Jul 12 11:27:56 2014
@@ -462,7 +462,7 @@
* use ast_json_ref() to safely keep a pointer to it.
*
* \param array JSON array to modify.
- * \param value New JSON value to store at the end of \a array.
+ * \param value New JSON value to store at the fend of \a array.
* \return 0 on success.
* \return -1 on error.
*/
@@ -1010,6 +1010,8 @@
*/
struct ast_json *ast_json_party_id(struct ast_party_id *party);
+int ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables);
+
/*!@}*/
#endif /* _ASTERISK_JSON_H */
Modified: team/mjordan/12-messaging/include/asterisk/manager.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/manager.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/manager.h (original)
+++ team/mjordan/12-messaging/include/asterisk/manager.h Sat Jul 12 11:27:56 2014
@@ -94,8 +94,16 @@
/*! \brief Export manager structures */
#define AST_MAX_MANHEADERS 128
-/*! \brief Manager Helper Function */
-typedef int (*manager_hook_t)(int, const char *, char *);
+/*! \brief Manager Helper Function
+ *
+ * \param category The class authorization category of the event
+ * \param event The name of the event being raised
+ * \param body The body of the event
+ *
+ * \retval 0 Success
+ * \retval non-zero Error
+ */
+typedef int (*manager_hook_t)(int category, const char *event, char *body);
struct manager_custom_hook {
/*! Identifier */
Modified: team/mjordan/12-messaging/include/asterisk/message.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/message.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/message.h (original)
+++ team/mjordan/12-messaging/include/asterisk/message.h Sat Jul 12 11:27:56 2014
@@ -25,8 +25,9 @@
*
* The purpose of this API is to provide support for text messages that
* are not session based. The messages are passed into the Asterisk core
- * to be routed through the dialplan and potentially sent back out through
- * a message technology that has been registered through this API.
+ * to be routed through the dialplan or another interface and potentially
+ * sent back out through a message technology that has been registered
+ * through this API.
*/
#ifndef __AST_MESSAGE_H__
@@ -91,6 +92,64 @@
int ast_msg_tech_unregister(const struct ast_msg_tech *tech);
/*!
+ * \brief An external processor of received messages
+ * \since 12.5.0
+ */
+struct ast_msg_handler {
+ /*!
+ * \brief Name of the message handler
+ */
+ const char *name;
+
+ /*!
+ * \brief The function callback that will handle the message
+ *
+ * \param msg The message to handle
+ *
+ * \retval 0 The handler processed the message successfull
+ * \retval non-zero The handler passed or could not process the message
+ */
+ int (* const handle_msg)(struct ast_msg *msg);
+
+ /*!
+ * \brief Return whether or not the message has a valid destination
+ *
+ * A message may be delivered to the dialplan and/or other locations,
+ * depending on whether or not other handlers have been registered. This
+ * function is called by the message core to determine if any handler can
+ * process a message.
+ *
+ * \param msg The message to inspect
+ *
+ * \retval 0 The message does not have a valid destination
+ * \retval 1 The message has a valid destination
+ */
+ int (* const has_destination)(const struct ast_msg *msg);
+};
+
+/*!
+ * \brief Register a \c ast_msg_handler
+ * \since 12.5.0
+ *
+ * \param handler The handler to register
+ *
+ * \retval 0 Success
+ * \retval non-zero Error
+ */
+int ast_msg_handler_register(const struct ast_msg_handler *handler);
+
+/*!
+ * \brief Unregister a \c ast_msg_handler
+ * \since 12.5.0
+ *
+ * \param handler The handler to unregister
+ *
+ * \retval 0 Success
+ * \retval non-zero Error
+ */
+int ast_msg_handler_unregister(const struct ast_msg_handler *handler);
+
+/*!
* \brief Allocate a message.
*
* Allocate a message for the purposes of passing it into the Asterisk core
@@ -162,6 +221,12 @@
*/
int __attribute__((format(printf, 2, 3)))
ast_msg_set_exten(struct ast_msg *msg, const char *fmt, ...);
+
+int __attribute__((format(printf, 2, 3)))
+ ast_msg_set_tech(struct ast_msg *msg, const char *fmt, ...);
+
+int __attribute__((format(printf, 2, 3)))
+ ast_msg_set_endpoint(struct ast_msg *msg, const char *fmt, ...);
/*!
* \brief Set a variable on the message going to the dialplan.
@@ -207,6 +272,42 @@
* \return The body of the messsage, encoded in UTF-8.
*/
const char *ast_msg_get_body(const struct ast_msg *msg);
+
+/*!
+ * \brief Retrieve the source of this message
+ * \since 12.5.0
+ *
+ * \param msg The message to get the soure from
+ *
+ * \retval The source of the message
+ * \retval NULL or empty string if the message has no source
+ */
+const char *ast_msg_get_from(const struct ast_msg *msg);
+
+/*!
+ * \brief Retrieve the destination of this message
+ * \since 12.5.0
+ *
+ * \param msg The message to get the destination from
+ *
+ * \retval The destination of the message
+ * \retval NULL or empty string if the message has no destination
+ */
+const char *ast_msg_get_to(const struct ast_msg *msg);
+
+const char *ast_msg_get_tech(const struct ast_msg *msg);
+const char *ast_msg_get_endpoint(const struct ast_msg *msg);
+
+/*!
+ * \brief Determine if a particular message has a destination via some handler
+ * \since 12.5.0
+ *
+ * \param msg The message to check
+ *
+ * \retval 0 if the message has no handler that can find a destination
+ * \retval 1 if the message has a handler that can find a destination
+ */
+int ast_msg_has_destination(const struct ast_msg *msg);
/*!
* \brief Queue a message for routing through the dialplan.
Modified: team/mjordan/12-messaging/include/asterisk/vector.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/vector.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/vector.h (original)
+++ team/mjordan/12-messaging/include/asterisk/vector.h Sat Jul 12 11:27:56 2014
@@ -61,7 +61,7 @@
#define AST_VECTOR_INIT(vec, size) ({ \
size_t __size = (size); \
size_t alloc_size = __size * sizeof(*((vec)->elems)); \
- (vec)->elems = alloc_size ? ast_malloc(alloc_size) : NULL; \
+ (vec)->elems = alloc_size ? ast_calloc(1, alloc_size) : NULL; \
(vec)->current = 0; \
if ((vec)->elems) { \
(vec)->max = __size; \
@@ -116,6 +116,48 @@
})
/*!
+ * \brief Insert an element at a specific position in a vector, growing the vector if needed.
+ *
+ * \param vec Vector to insert into.
+ * \param idx Position to insert at.
+ * \param elem Element to insert.
+ *
+ * \return 0 on success.
+ * \return Non-zero on failure.
+ *
+ * \warning This macro will overwrite anything already present at the position provided.
+ *
+ * \warning Use of this macro with the expectation that the element will remain at the provided
+ * index means you can not use the UNORDERED assortment of macros. These macros alter the ordering
+ * of the vector itself.
+ */
+#define AST_VECTOR_INSERT(vec, idx, elem) ({ \
+ int res = 0; \
+ do { \
+ if (((idx) + 1) > (vec)->max) { \
+ size_t new_max = ((idx) + 1) * 2; \
+ typeof((vec)->elems) new_elems = ast_calloc(1, \
+ new_max * sizeof(*new_elems)); \
+ if (new_elems) { \
+ memcpy(new_elems, (vec)->elems, \
+ (vec)->current * sizeof(*new_elems)); \
+ ast_free((vec)->elems); \
+ (vec)->elems = new_elems; \
+ (vec)->max = new_max; \
+ } else { \
+ res = -1; \
+ break; \
+ } \
+ } \
+ (vec)->elems[(idx)] = (elem); \
+ if (((idx) + 1) > (vec)->current) { \
+ (vec)->current = (idx) + 1; \
+ } \
+ } while(0); \
+ res; \
+})
+
+/*!
* \brief Remove an element from a vector by index.
*
* Note that elements in the vector may be reordered, so that the remove can
Modified: team/mjordan/12-messaging/include/asterisk/xmpp.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/include/asterisk/xmpp.h?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/include/asterisk/xmpp.h (original)
+++ team/mjordan/12-messaging/include/asterisk/xmpp.h Sat Jul 12 11:27:56 2014
@@ -106,6 +106,8 @@
AST_LIST_ENTRY(ast_xmpp_message) list; /*!< Linked list information */
};
+struct ast_endpoint;
+
/*! \brief XMPP Buddy */
struct ast_xmpp_buddy {
char id[XMPP_MAX_JIDLEN]; /*!< JID of the buddy */
@@ -116,9 +118,11 @@
/*! \brief XMPP Client Connection */
struct ast_xmpp_client {
AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name); /*!< Name of the client configuration */
+ /*! Name of the client configuration */
+ AST_STRING_FIELD(name);
);
- char mid[6]; /* Message ID */
+ /*! Message ID */
+ char mid[6];
iksid *jid;
iksparser *parser;
iksfilter *filter;
@@ -134,9 +138,14 @@
AST_LIST_HEAD(, ast_xmpp_message) messages;
pthread_t thread;
int timeout;
- unsigned int reconnect:1; /*!< Reconnect this client */
- struct stasis_subscription *mwi_sub; /*!< If distributing event information the MWI subscription */
- struct stasis_subscription *device_state_sub; /*!< If distributing event information the device state subscription */
+ /*! Reconnect this client */
+ unsigned int reconnect:1;
+ /*! If distributing event information the MWI subscription */
+ struct stasis_subscription *mwi_sub;
+ /*! If distributing event information the device state subscription */
+ struct stasis_subscription *device_state_sub;
+ /*! The endpoint associated with this client */
+ struct ast_endpoint *endpoint;
};
/*!
Modified: team/mjordan/12-messaging/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/main/channel.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/main/channel.c (original)
+++ team/mjordan/12-messaging/main/channel.c Sat Jul 12 11:27:56 2014
@@ -855,10 +855,11 @@
static void ast_dummy_channel_destructor(void *obj);
/*! \brief Create a new channel structure */
-static struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 0)))
+static struct ast_channel * attribute_malloc __attribute__((format(printf, 15, 0)))
__ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char *cid_name,
const char *acctcode, const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
- const struct ast_channel *requestor, enum ama_flags amaflag, const char *file, int line,
+ const struct ast_channel *requestor, enum ama_flags amaflag, struct ast_endpoint *endpoint,
+ const char *file, int line,
const char *function, const char *name_fmt, va_list ap)
{
struct ast_channel *tmp;
@@ -1028,6 +1029,10 @@
ao2_link(channels, tmp);
+ if (endpoint) {
+ ast_endpoint_add_channel(endpoint, tmp);
+ }
+
/*
* And now, since the channel structure is built, and has its name, let
* the world know of its existance
@@ -1040,6 +1045,7 @@
const char *cid_name, const char *acctcode,
const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
const struct ast_channel *requestor, enum ama_flags amaflag,
+ struct ast_endpoint *endpoint,
const char *file, int line, const char *function,
const char *name_fmt, ...)
{
@@ -1048,7 +1054,7 @@
va_start(ap, name_fmt);
result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
- assignedids, requestor, amaflag, file, line, function, name_fmt, ap);
+ assignedids, requestor, amaflag, endpoint, file, line, function, name_fmt, ap);
va_end(ap);
return result;
Modified: team/mjordan/12-messaging/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/main/channel_internal_api.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/main/channel_internal_api.c (original)
+++ team/mjordan/12-messaging/main/channel_internal_api.c Sat Jul 12 11:27:56 2014
@@ -219,6 +219,7 @@
struct timeval sending_dtmf_tv; /*!< The time this channel started sending the current digit. (Invalid if sending_dtmf_digit is zero.) */
struct stasis_cp_single *topics; /*!< Topic for all channel's events */
struct stasis_forward *endpoint_forward; /*!< Subscription for event forwarding to endpoint's topic */
+ struct stasis_forward *endpoint_cache_forward; /*!< Subscription for cache updates to endpoint's topic */
};
/*! \brief The monotonically increasing integer counter for channel uniqueids */
@@ -1502,6 +1503,7 @@
ast_string_field_free_memory(chan);
chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
+ chan->endpoint_cache_forward = stasis_forward_cancel(chan->endpoint_cache_forward);
stasis_cp_single_unsubscribe(chan->topics);
chan->topics = NULL;
@@ -1544,8 +1546,14 @@
chan->endpoint_forward =
stasis_forward_all(ast_channel_topic(chan),
ast_endpoint_topic(endpoint));
-
- if (chan->endpoint_forward == NULL) {
+ if (!chan->endpoint_forward) {
+ return -1;
+ }
+
+ chan->endpoint_cache_forward = stasis_forward_all(ast_channel_topic_cached(chan),
+ ast_endpoint_topic(endpoint));
+ if (!chan->endpoint_cache_forward) {
+ chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
return -1;
}
Modified: team/mjordan/12-messaging/main/endpoints.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/main/endpoints.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/main/endpoints.c (original)
+++ team/mjordan/12-messaging/main/endpoints.c Sat Jul 12 11:27:56 2014
@@ -46,7 +46,12 @@
/*! Buckets for endpoint hash. Keep it prime! */
#define ENDPOINT_BUCKETS 127
+/*! Buckets for technology endpoints. */
+#define TECH_ENDPOINT_BUCKETS 11
+
static struct ao2_container *endpoints;
+
+static struct ao2_container *tech_endpoints;
struct ast_endpoint {
AST_DECLARE_STRING_FIELDS(
@@ -69,6 +74,8 @@
struct stasis_message_router *router;
/*! ast_str_container of channels associated with this endpoint */
struct ao2_container *channel_ids;
+ /*! Forwarding subscription from an endpoint to its tech endpoint */
+ struct stasis_forward *tech_forward;
};
static int endpoint_hash(const void *obj, int flags)
@@ -121,7 +128,13 @@
struct ast_endpoint *ast_endpoint_find_by_id(const char *id)
{
- return ao2_find(endpoints, id, OBJ_KEY);
+ struct ast_endpoint *endpoint = ao2_find(endpoints, id, OBJ_KEY);
+
+ if (!endpoint) {
+ endpoint = ao2_find(tech_endpoints, id, OBJ_KEY);
+ }
+
+ return endpoint;
}
struct stasis_topic *ast_endpoint_topic(struct ast_endpoint *endpoint)
@@ -181,6 +194,8 @@
ao2_cleanup(endpoint->router);
endpoint->router = NULL;
+ endpoint->tech_forward = stasis_forward_cancel(endpoint->tech_forward);
+
stasis_cp_single_unsubscribe(endpoint->topics);
endpoint->topics = NULL;
@@ -196,6 +211,7 @@
{
ast_assert(chan != NULL);
ast_assert(endpoint != NULL);
+ ast_assert(!ast_strlen_zero(endpoint->resource));
ast_channel_forward_endpoint(chan, endpoint);
@@ -242,19 +258,21 @@
}
}
-struct ast_endpoint *ast_endpoint_create(const char *tech, const char *resource)
+static struct ast_endpoint *endpoint_internal_create(const char *tech, const char *resource)
{
RAII_VAR(struct ast_endpoint *, endpoint, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_endpoint *, tech_endpoint, NULL, ao2_cleanup);
int r = 0;
- if (ast_strlen_zero(tech)) {
- ast_log(LOG_ERROR, "Endpoint tech cannot be empty\n");
- return NULL;
- }
-
- if (ast_strlen_zero(resource)) {
- ast_log(LOG_ERROR, "Endpoint resource cannot be empty\n");
- return NULL;
+ /* Get/create the technology endpoint */
+ if (!ast_strlen_zero(resource)) {
+ tech_endpoint = ao2_find(tech_endpoints, tech, OBJ_KEY);
+ if (!tech_endpoint) {
+ tech_endpoint = endpoint_internal_create(tech, NULL);
+ if (!tech_endpoint) {
+ return NULL;
+ }
+ }
}
endpoint = ao2_alloc(sizeof(*endpoint), endpoint_dtor);
@@ -268,10 +286,12 @@
if (ast_string_field_init(endpoint, 80) != 0) {
return NULL;
}
-
ast_string_field_set(endpoint, tech, tech);
- ast_string_field_set(endpoint, resource, resource);
- ast_string_field_build(endpoint, id, "%s/%s", tech, resource);
+ ast_string_field_set(endpoint, resource, S_OR(resource, ""));
+ ast_string_field_build(endpoint, id, "%s%s%s",
+ tech,
+ !ast_strlen_zero(resource) ? "/" : "",
+ S_OR(resource, ""));
/* All access to channel_ids should be covered by the endpoint's
* lock; no extra lock needed. */
@@ -287,22 +307,45 @@
return NULL;
}
- endpoint->router = stasis_message_router_create(ast_endpoint_topic(endpoint));
- if (!endpoint->router) {
- return NULL;
- }
- r |= stasis_message_router_add(endpoint->router,
- stasis_cache_clear_type(), endpoint_cache_clear,
- endpoint);
- r |= stasis_message_router_set_default(endpoint->router,
- endpoint_default, endpoint);
-
- endpoint_publish_snapshot(endpoint);
-
- ao2_link(endpoints, endpoint);
+ if (!ast_strlen_zero(resource)) {
+ endpoint->router = stasis_message_router_create(ast_endpoint_topic(endpoint));
+ if (!endpoint->router) {
+ return NULL;
+ }
+ r |= stasis_message_router_add(endpoint->router,
+ stasis_cache_clear_type(), endpoint_cache_clear,
+ endpoint);
+ r |= stasis_message_router_set_default(endpoint->router,
+ endpoint_default, endpoint);
+ if (r) {
+ return NULL;
+ }
+
+ endpoint->tech_forward = stasis_forward_all(stasis_cp_single_topic(endpoint->topics),
+ stasis_cp_single_topic(tech_endpoint->topics));
+ endpoint_publish_snapshot(endpoint);
+ ao2_link(endpoints, endpoint);
+ } else {
+ ao2_link(tech_endpoints, endpoint);
+ }
ao2_ref(endpoint, +1);
return endpoint;
+}
+
+struct ast_endpoint *ast_endpoint_create(const char *tech, const char *resource)
+{
+ if (ast_strlen_zero(tech)) {
+ ast_log(LOG_ERROR, "Endpoint tech cannot be empty\n");
+ return NULL;
+ }
+
+ if (ast_strlen_zero(resource)) {
+ ast_log(LOG_ERROR, "Endpoint resource cannot be empty\n");
+ return NULL;
+ }
+
+ return endpoint_internal_create(tech, resource);
}
static struct stasis_message *create_endpoint_snapshot_message(struct ast_endpoint *endpoint)
@@ -368,6 +411,8 @@
enum ast_endpoint_state state)
{
ast_assert(endpoint != NULL);
+ ast_assert(!ast_strlen_zero(endpoint->resource));
+
ao2_lock(endpoint);
endpoint->state = state;
ao2_unlock(endpoint);
@@ -378,6 +423,8 @@
int max_channels)
{
ast_assert(endpoint != NULL);
+ ast_assert(!ast_strlen_zero(endpoint->resource));
+
ao2_lock(endpoint);
endpoint->max_channels = max_channels;
ao2_unlock(endpoint);
@@ -407,6 +454,9 @@
void *obj;
SCOPED_AO2LOCK(lock, endpoint);
+ ast_assert(endpoint != NULL);
+ ast_assert(!ast_strlen_zero(endpoint->resource));
+
channel_count = ao2_container_count(endpoint->channel_ids);
snapshot = ao2_alloc(
@@ -440,6 +490,9 @@
{
ao2_cleanup(endpoints);
endpoints = NULL;
+
+ ao2_cleanup(tech_endpoints);
+ tech_endpoints = NULL;
}
int ast_endpoint_init(void)
@@ -448,10 +501,15 @@
endpoints = ao2_container_alloc(ENDPOINT_BUCKETS, endpoint_hash,
endpoint_cmp);
-
if (!endpoints) {
return -1;
}
+ tech_endpoints = ao2_container_alloc(TECH_ENDPOINT_BUCKETS, endpoint_hash,
+ endpoint_cmp);
+ if (!tech_endpoints) {
+ return -1;
+ }
+
return 0;
}
Modified: team/mjordan/12-messaging/main/json.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/main/json.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/main/json.c (original)
+++ team/mjordan/12-messaging/main/json.c Sat Jul 12 11:27:56 2014
@@ -881,3 +881,28 @@
return ast_json_ref(json_party_id);
}
+
+int ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
+{
+ struct ast_json_iter *it_json_var;
+
+ *variables = NULL;
+
+ for (it_json_var = ast_json_object_iter(json_variables); it_json_var;
+ it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) {
+ struct ast_variable *new_var;
+
+ new_var = ast_variable_new(ast_json_object_iter_key(it_json_var),
+ ast_json_string_get(ast_json_object_iter_value(it_json_var)),
+ "");
+ if (!new_var) {
+ ast_variables_destroy(*variables);
+ *variables = NULL;
+ return 1;
+ }
+
+ ast_variable_list_append(variables, new_var);
+ }
+
+ return 0;
+}
Modified: team/mjordan/12-messaging/main/message.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-messaging/main/message.c?view=diff&rev=418441&r1=418440&r2=418441
==============================================================================
--- team/mjordan/12-messaging/main/message.c (original)
+++ team/mjordan/12-messaging/main/message.c Sat Jul 12 11:27:56 2014
@@ -39,6 +39,7 @@
#include "asterisk/manager.h"
#include "asterisk/strings.h"
#include "asterisk/astobj2.h"
+#include "asterisk/vector.h"
#include "asterisk/app.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/message.h"
@@ -201,7 +202,7 @@
AST_STRING_FIELD(name);
AST_STRING_FIELD(value);
);
- unsigned int send:1; /* Whether to send out on outbound messages */
+ unsigned int send; /* Whether to send out on outbound messages */
};
AST_LIST_HEAD_NOLOCK(outhead, msg_data);
@@ -212,26 +213,29 @@
* \todo Consider whether stringfields would be an appropriate optimization here.
*/
struct ast_msg {
- struct ast_str *to;
- struct ast_str *from;
- struct ast_str *body;
- struct ast_str *context;
- struct ast_str *exten;
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(to);
+ AST_STRING_FIELD(from);
+ AST_STRING_FIELD(body);
+ AST_STRING_FIELD(context);
+ AST_STRING_FIELD(exten);
+ AST_STRING_FIELD(endpoint);
+ AST_STRING_FIELD(tech);
+ );
struct ao2_container *vars;
};
-struct ast_msg_tech_holder {
- const struct ast_msg_tech *tech;
- /*!
- * \brief A rwlock for this object
- *
- * a read/write lock must be used to protect the wrapper instead
- * of the ao2 lock. A rdlock must be held to read tech_holder->tech.
- */
- ast_rwlock_t tech_lock;
-};
-
-static struct ao2_container *msg_techs;
+/*! \brief Lock for \c msg_techs vector */
+static ast_rwlock_t msg_techs_lock;
+
+/*! \brief Vector of message technologies */
+AST_VECTOR(, const struct ast_msg_tech *) msg_techs;
+
+/*! \brief Lock for \c msg_handlers vector */
+static ast_rwlock_t msg_handlers_lock;
+
+/*! \brief Vector of received message handlers */
+AST_VECTOR(, const struct ast_msg_handler *) msg_handlers;
static struct ast_taskprocessor *msg_q_tp;
@@ -387,21 +391,7 @@
{
struct ast_msg *msg = obj;
- ast_free(msg->to);
- msg->to = NULL;
-
- ast_free(msg->from);
- msg->from = NULL;
-
- ast_free(msg->body);
- msg->body = NULL;
-
- ast_free(msg->context);
- msg->context = NULL;
-
- ast_free(msg->exten);
- msg->exten = NULL;
-
+ ast_string_field_free_memory(msg);
ao2_ref(msg->vars, -1);
}
@@ -413,27 +403,7 @@
return NULL;
}
- if (!(msg->to = ast_str_create(32))) {
- ao2_ref(msg, -1);
- return NULL;
- }
-
- if (!(msg->from = ast_str_create(32))) {
- ao2_ref(msg, -1);
- return NULL;
- }
-
- if (!(msg->body = ast_str_create(128))) {
- ao2_ref(msg, -1);
- return NULL;
- }
-
- if (!(msg->context = ast_str_create(16))) {
- ao2_ref(msg, -1);
- return NULL;
- }
-
- if (!(msg->exten = ast_str_create(16))) {
+ if (ast_string_field_init(msg, 128)) {
ao2_ref(msg, -1);
return NULL;
}
@@ -442,8 +412,7 @@
ao2_ref(msg, -1);
return NULL;
}
-
- ast_str_set(&msg->context, 0, "default");
+ ast_string_field_set(msg, context, "default");
return msg;
}
@@ -457,73 +426,109 @@
struct ast_msg *ast_msg_destroy(struct ast_msg *msg)
{
ao2_ref(msg, -1);
-
return NULL;
}
int ast_msg_set_to(struct ast_msg *msg, const char *fmt, ...)
{
va_list ap;
- int res;
va_start(ap, fmt);
- res = ast_str_set_va(&msg->to, 0, fmt, ap);
+ ast_string_field_build_va(msg, to, fmt, ap);
va_end(ap);
- return res < 0 ? -1 : 0;
+ return 0;
}
int ast_msg_set_from(struct ast_msg *msg, const char *fmt, ...)
{
va_list ap;
- int res;
va_start(ap, fmt);
- res = ast_str_set_va(&msg->from, 0, fmt, ap);
+ ast_string_field_build_va(msg, from, fmt, ap);
va_end(ap);
- return res < 0 ? -1 : 0;
+ return 0;
}
int ast_msg_set_body(struct ast_msg *msg, const char *fmt, ...)
{
va_list ap;
- int res;
va_start(ap, fmt);
- res = ast_str_set_va(&msg->body, 0, fmt, ap);
+ ast_string_field_build_va(msg, body, fmt, ap);
va_end(ap);
- return res < 0 ? -1 : 0;
+ return 0;
}
[... 3177 lines stripped ...]
More information about the asterisk-commits
mailing list