summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-04-08 13:27:45 +0000
committerDavid M. Lee <dlee@digium.com>2013-04-08 13:27:45 +0000
commita2a53cc306ea5fec65daf3630716a7c6ee13adad (patch)
tree4e59f10e2c6ab044ac307466bf921bbf1ceca7d3 /include
parent426095bc5503391eabb3e5ce0fbbfec8b4752f2d (diff)
Stasis application WebSocket support
This is the API that binds the Stasis dialplan application to external Stasis applications. It also adds the beginnings of WebSocket application support. This module registers a dialplan function named Stasis, which is used to put a channel into the named Stasis app. As a channel enters and leaves the Stasis diaplan application, the Stasis app receives a 'stasis-start' and 'stasis-end' events. Stasis apps register themselves using the stasis_app_register and stasis_app_unregister functions. Messages are sent to an application using stasis_app_send. Finally, Stasis apps control channels through the use of the stasis_app_control object, and the family of stasis_app_control_* functions. Other changes along for the ride are: * An ast_frame_dtor function that's RAII_VAR safe * Some common JSON encoders for name/number, timeval, and context/extension/priority Review: https://reviewboard.asterisk.org/r/2361/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@384879 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/app_stasis.h138
-rw-r--r--include/asterisk/frame.h74
-rw-r--r--include/asterisk/json.h44
-rw-r--r--include/asterisk/localtime.h5
4 files changed, 227 insertions, 34 deletions
diff --git a/include/asterisk/app_stasis.h b/include/asterisk/app_stasis.h
new file mode 100644
index 000000000..921a35ee8
--- /dev/null
+++ b/include/asterisk/app_stasis.h
@@ -0,0 +1,138 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012 - 2013, Digium, Inc.
+ *
+ * David M. Lee, II <dlee@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _ASTERISK_APP_STASIS_H
+#define _ASTERISK_APP_STASIS_H
+
+/*! \file
+ *
+ * \brief Stasis Application API. See \ref app_stasis "Stasis Application API"
+ * for detailed documentation.
+ *
+ * \author David M. Lee, II <dlee@digium.com>
+ * \since 12
+ *
+ * \page app_stasis Stasis Application API
+ *
+ * This is the API that binds the Stasis dialplan application to external
+ * Stasis applications, such as \c res_stasis_websocket.
+ *
+ * This module registers a dialplan function named \c Stasis, which is used to
+ * put a channel into the named Stasis app. As a channel enters and leaves the
+ * Stasis diaplan applcation, the Stasis app receives a \c 'stasis-start' and \c
+ * 'stasis-end' events.
+ *
+ * Stasis apps register themselves using the \ref stasis_app_register and
+ * stasis_app_unregister functions. Messages are sent to an appliction using
+ * \ref stasis_app_send.
+ *
+ * Finally, Stasis apps control channels through the use of the \ref
+ * stasis_app_control object, and the family of \c stasis_app_control_*
+ * functions.
+ */
+
+#include "asterisk/channel.h"
+#include "asterisk/json.h"
+
+/*! @{ */
+
+/*!
+ * \brief Callback for Stasis application handler.
+ *
+ * The message given to the handler is a borrowed copy. If you want to keep a
+ * reference to it, you should use \c ao2_ref() to keep it around.
+ *
+ * \param data Data ptr given when registered.
+ * \param app_name Name of the application being dispatched to.
+ * \param message Message to handle. (borrowed copy)
+ */
+typedef void (*stasis_app_cb)(void *data, const char *app_name,
+ struct ast_json *message);
+
+/*!
+ * \brief Register a new Stasis application.
+ *
+ * If an application is already registered with the given name, the old
+ * application is sent a 'replaced' message and unregistered.
+ *
+ * \param app_name Name of this application.
+ * \param handler Callback for application messages.
+ * \param data Data blob to pass to the callback. Must be AO2 managed.
+ * \return 0 for success
+ * \return -1 for error.
+ */
+int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data);
+
+/*!
+ * \brief Unregister a Stasis application.
+ * \param app_name Name of the application to unregister.
+ */
+void stasis_app_unregister(const char *app_name);
+
+/*!
+ * \brief Send a message to the given Stasis application.
+ *
+ * The message given to the handler is a borrowed copy. If you want to keep a
+ * reference to it, you should use \c ao2_ref() to keep it around.
+ *
+ * \param app_name Name of the application to invoke.
+ * \param message Message to send (borrowed reference)
+ * \return 0 for success.
+ * \return -1 for error.
+ */
+int stasis_app_send(const char *app_name, struct ast_json *message);
+
+/*! @} */
+
+/*! @{ */
+
+/*! \brief Handler for controlling a channel that's in a Stasis application */
+struct stasis_app_control;
+
+/*!
+ * \brief Returns the handler for the given channel
+ * \param chan Channel to handle.
+ * \return NULL channel not in Stasis application
+ * \return Pointer to app_stasis handler.
+ */
+struct stasis_app_control *stasis_app_control_find_by_channel(
+ const struct ast_channel *chan);
+
+/*!
+ * \brief Exit \c app_stasis and continue execution in the dialplan.
+ *
+ * If the channel is no longer in \c app_stasis, this function does nothing.
+ *
+ * \param handler Handler for \c app_stasis
+ */
+void stasis_app_control_continue(struct stasis_app_control *handler);
+
+/*! @} */
+
+/*! @{ */
+
+/*!
+ * \brief Build a JSON object from a \ref ast_channel_snapshot.
+ * \return JSON object representing channel snapshot.
+ * \return \c NULL on error
+ */
+struct ast_json *ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot);
+
+/*! @} */
+
+#endif /* _ASTERISK_APP_STASIS_H */
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 5e81b4e18..abb0c2e28 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -39,11 +39,11 @@ extern "C" {
/*!
* \page Def_Frame AST Multimedia and signalling frames
* \section Def_AstFrame What is an ast_frame ?
- * A frame of data read used to communicate between
+ * A frame of data read used to communicate between
* between channels and applications.
* Frames are divided into frame types and subclasses.
*
- * \par Frame types
+ * \par Frame types
* \arg \b VOICE: Voice data, subclass is codec (AST_FORMAT_*)
* \arg \b VIDEO: Video data, subclass is codec (AST_FORMAT_*)
* \arg \b DTMF: A DTMF digit, subclass is the digit
@@ -88,7 +88,7 @@ extern "C" {
*/
/*!
- * \brief Frame types
+ * \brief Frame types
*
* \note It is important that the values of each frame type are never changed,
* because it will break backwards compatability with older versions.
@@ -113,11 +113,11 @@ enum ast_frame_type {
AST_FRAME_IMAGE,
/*! HTML Frame */
AST_FRAME_HTML,
- /*! Comfort Noise frame (subclass is level of CNG in -dBov),
+ /*! Comfort Noise frame (subclass is level of CNG in -dBov),
body may include zero or more 8-bit quantization coefficients */
AST_FRAME_CNG,
/*! Modem-over-IP data streams */
- AST_FRAME_MODEM,
+ AST_FRAME_MODEM,
/*! DTMF begin event, subclass is the digit */
AST_FRAME_DTMF_BEGIN,
};
@@ -137,24 +137,24 @@ union ast_frame_subclass {
*/
struct ast_frame {
/*! Kind of frame */
- enum ast_frame_type frametype;
+ enum ast_frame_type frametype;
/*! Subclass, frame dependent */
union ast_frame_subclass subclass;
/*! Length of data */
- int datalen;
+ int datalen;
/*! Number of samples in this frame */
- int samples;
+ int samples;
/*! Was the data malloc'd? i.e. should we free it when we discard the frame? */
- int mallocd;
+ int mallocd;
/*! The number of bytes allocated for a malloc'd frame header */
size_t mallocd_hdr_len;
/*! How many bytes exist _before_ "data" that can be used if needed */
- int offset;
+ int offset;
/*! Optional source of frame for debugging */
- const char *src;
+ const char *src;
/*! Pointer to actual data */
union { void *ptr; uint32_t uint32; char pad[8]; } data;
- /*! Global delivery time */
+ /*! Global delivery time */
struct timeval delivery;
/*! For placing in a linked list */
AST_LIST_ENTRY(ast_frame) frame_list;
@@ -197,7 +197,7 @@ extern struct ast_frame ast_null_frame;
* RTP header information into the space provided by AST_FRIENDLY_OFFSET instead
* of having to create a new buffer with the necessary space allocated.
*/
-#define AST_FRIENDLY_OFFSET 64
+#define AST_FRIENDLY_OFFSET 64
#define AST_MIN_OFFSET 32 /*! Make sure we keep at least this much handy */
/*! Need the header be free'd? */
@@ -353,10 +353,10 @@ struct ast_control_pvt_cause_code {
#define AST_OPTION_FLAG_ANSWER 5
#define AST_OPTION_FLAG_WTF 6
-/*! Verify touchtones by muting audio transmission
+/*! Verify touchtones by muting audio transmission
* (and reception) and verify the tone is still present
* Option data is a single signed char value 0 or 1 */
-#define AST_OPTION_TONE_VERIFY 1
+#define AST_OPTION_TONE_VERIFY 1
/*! Put a compatible channel into TDD (TTY for the hearing-impared) mode
* Option data is a single signed char value 0 or 1 */
@@ -370,7 +370,7 @@ struct ast_control_pvt_cause_code {
* Option data is a single signed char value 0 or 1 */
#define AST_OPTION_AUDIO_MODE 4
-/*! Set channel transmit gain
+/*! Set channel transmit gain
* Option data is a single signed char representing number of decibels (dB)
* to set gain to (on top of any gain specified in channel driver) */
#define AST_OPTION_TXGAIN 5
@@ -380,7 +380,7 @@ struct ast_control_pvt_cause_code {
* to set gain to (on top of any gain specified in channel driver) */
#define AST_OPTION_RXGAIN 6
-/* set channel into "Operator Services" mode
+/* set channel into "Operator Services" mode
* Option data is a struct oprmode
*
* \note This option should never be sent over the network */
@@ -433,7 +433,7 @@ struct ast_control_pvt_cause_code {
* Option data is a character buffer of suitable length */
#define AST_OPTION_DEVICE_NAME 16
-/*! Get the CC agent type from the channel (Read only)
+/*! Get the CC agent type from the channel (Read only)
* Option data is a character buffer of suitable length */
#define AST_OPTION_CC_AGENT_TYPE 17
@@ -450,12 +450,12 @@ struct oprmode {
struct ast_option_header {
/* Always keep in network byte order */
#if __BYTE_ORDER == __BIG_ENDIAN
- uint16_t flag:3;
- uint16_t option:13;
+ uint16_t flag:3;
+ uint16_t option:13;
#else
#if __BYTE_ORDER == __LITTLE_ENDIAN
- uint16_t option:13;
- uint16_t flag:3;
+ uint16_t option:13;
+ uint16_t flag:3;
#else
#error Byte order not defined
#endif
@@ -463,19 +463,19 @@ struct ast_option_header {
uint8_t data[0];
};
-/*! \brief Requests a frame to be allocated
- *
- * \param source
- * Request a frame be allocated. source is an optional source of the frame,
- * len is the requested length, or "0" if the caller will supply the buffer
+/*! \brief Requests a frame to be allocated
+ *
+ * \param source
+ * Request a frame be allocated. source is an optional source of the frame,
+ * len is the requested length, or "0" if the caller will supply the buffer
*/
#if 0 /* Unimplemented */
struct ast_frame *ast_fralloc(char *source, int len);
#endif
-/*!
+/*!
* \brief Frees a frame or list of frames
- *
+ *
* \param fr Frame to free, or head of list to free
* \param cache Whether to consider this frame for frame caching
*/
@@ -483,6 +483,12 @@ void ast_frame_free(struct ast_frame *fr, int cache);
#define ast_frfree(fr) ast_frame_free(fr, 1)
+/*!
+ * \brief NULL-safe wrapper for \ref ast_frfree, good for \ref RAII_VAR.
+ * \param frame Frame to free, or head of list to free.
+ */
+void ast_frame_dtor(struct ast_frame *frame);
+
/*! \brief Makes a frame independent of any static storage
* \param fr frame to act upon
* Take a frame, and if it's not been malloc'd, make a malloc'd copy
@@ -498,7 +504,7 @@ void ast_frame_free(struct ast_frame *fr, int cache);
*/
struct ast_frame *ast_frisolate(struct ast_frame *fr);
-/*! \brief Copies a frame
+/*! \brief Copies a frame
* \param fr frame to copy
* Duplicates a frame -- should only rarely be used, typically frisolate is good enough
* \return Returns a frame on success, NULL on error
@@ -507,7 +513,7 @@ struct ast_frame *ast_frdup(const struct ast_frame *fr);
void ast_swapcopy_samples(void *dst, const void *src, int samples);
-/* Helpers for byteswapping native samples to/from
+/* Helpers for byteswapping native samples to/from
little-endian and big-endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define ast_frame_byteswap_le(fr) do { ; } while(0)
@@ -518,13 +524,13 @@ void ast_swapcopy_samples(void *dst, const void *src, int samples);
#endif
/*! \brief Parse an "allow" or "deny" line in a channel or device configuration
- and update the capabilities and pref if provided.
+ and update the capabilities and pref if provided.
Video codecs are not added to codec preference lists, since we can not transcode
\return Returns number of errors encountered during parsing
*/
int ast_parse_allow_disallow(struct ast_codec_pref *pref, struct ast_format_cap *cap, const char *list, int allowing);
-/*! \name AST_Smoother
+/*! \name AST_Smoother
*/
/*@{ */
/*! \page ast_smooth The AST Frame Smoother
@@ -584,7 +590,7 @@ struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f,
/*! \brief Gets duration in ms of interpolation frame for a format */
static inline int ast_codec_interp_len(struct ast_format *format)
-{
+{
return (format->id == AST_FORMAT_ILBC) ? 30 : 20;
}
diff --git a/include/asterisk/json.h b/include/asterisk/json.h
index d8cf98ece..64a1e7b7a 100644
--- a/include/asterisk/json.h
+++ b/include/asterisk/json.h
@@ -764,4 +764,48 @@ struct ast_json *ast_json_deep_copy(const struct ast_json *value);
/*!@}*/
+/*!@{*/
+
+/*!
+ * \brief Common JSON rendering functions for common 'objects'.
+ */
+
+/*!
+ * \brief Simple name/number pair.
+ * \param name Name
+ * \param number Number
+ * \return NULL if error (non-UTF8 characters, NULL inputs, etc.)
+ * \return JSON object with name and number fields
+ */
+struct ast_json *ast_json_name_number(const char *name, const char *number);
+
+/*!
+ * \brief Construct a timeval as JSON.
+ *
+ * JSON does not define a standard date format (boo), but the de facto standard
+ * is to use ISO 8601 formatted string. We build a millisecond resolution string
+ * from the \c timeval
+ *
+ * \param tv \c timeval to encode.
+ * \param zone Text string of a standard system zoneinfo file. If NULL, the system localtime will be used.
+ * \return JSON string with ISO 8601 formatted date/time.
+ * \return \c NULL on error.
+ */
+struct ast_json *ast_json_timeval(const struct timeval *tv, const char *zone);
+
+/*!
+ * \brief Construct a context/exten/priority as JSON.
+ *
+ * If a \c NULL is passed for \c context or \c exten, or -1 for \c priority,
+ * the fields is set to ast_json_null().
+ *
+ * \param context Context name.
+ * \param exten Extension.
+ * \param priority Dialplan priority.
+ * \return JSON object with \c context, \c exten and \c priority fields
+ */
+struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority);
+
+/*!@}*/
+
#endif /* _ASTERISK_JSON_H */
diff --git a/include/asterisk/localtime.h b/include/asterisk/localtime.h
index 50f5c835c..74f342c46 100644
--- a/include/asterisk/localtime.h
+++ b/include/asterisk/localtime.h
@@ -99,4 +99,9 @@ char *ast_strptime_locale(const char *s, const char *format, struct ast_tm *tm,
struct ast_test;
void ast_localtime_wakeup_monitor(struct ast_test *info);
+/*! \brief ast_strftime for ISO8601 formatting timestamps. */
+#define AST_ISO8601_FORMAT "%FT%T.%q%z"
+/*! \brief Max length of an null terminated, millisecond resolution, ISO8601 timestamp string. */
+#define AST_ISO8601_LEN 29
+
#endif /* _ASTERISK_LOCALTIME_H */