Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Macros | Enumerations | Functions | Variables
chan_audiosocket.c File Reference

AudioSocket Channel. More...

#include "asterisk.h"
#include <uuid/uuid.h>
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/res_audiosocket.h"
#include "asterisk/pbx.h"
#include "asterisk/acl.h"
#include "asterisk/app.h"
#include "asterisk/causes.h"
#include "asterisk/format_cache.h"
Include dependency graph for chan_audiosocket.c:

Go to the source code of this file.

Data Structures

struct  audiosocket_instance
 

Macros

#define FD_OUTPUT   1 /* A fd of -1 means an error, 0 is stdin */
 

Enumerations

enum  { OPT_AUDIOSOCKET_CODEC = (1 << 0) }
 
enum  { OPT_ARG_AUDIOSOCKET_CODEC = (1 << 0) , OPT_ARG_ARRAY_SIZE }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int audiosocket_call (struct ast_channel *ast, const char *dest, int timeout)
 Function called when we should actually call the destination. More...
 
static int audiosocket_hangup (struct ast_channel *ast)
 Function called when we should hang the channel up. More...
 
static struct ast_frameaudiosocket_read (struct ast_channel *ast)
 Function called when we should read a frame from the channel. More...
 
static struct ast_channelaudiosocket_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Function called when we should prepare to call the unicast destination. More...
 
static int audiosocket_send_dtmf (struct ast_channel *ast, char digit, unsigned int duration)
 Function called when we should write a DTMF frame to the channel. More...
 
static int audiosocket_write (struct ast_channel *ast, struct ast_frame *f)
 Function called when we should write a frame to the channel. More...
 
static int load_module (void)
 Function called when our module is loaded. More...
 
static int unload_module (void)
 Function called when our module is unloaded. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "AudioSocket Channel" , .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_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "res_audiosocket", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_channel_tech audiosocket_channel_tech
 
struct audiosocket_instance audiosocket_instance
 
static const struct ast_app_option audiosocket_options [128] = { [ 'c' ] = { .flag = OPT_AUDIOSOCKET_CODEC , .arg_index = OPT_ARG_AUDIOSOCKET_CODEC + 1 }, }
 

Detailed Description

AudioSocket Channel.

Author
Seán C McCord scm@c.nosp@m.ycor.nosp@m.esys..nosp@m.com

Definition in file chan_audiosocket.c.

Macro Definition Documentation

◆ FD_OUTPUT

#define FD_OUTPUT   1 /* A fd of -1 means an error, 0 is stdin */

Definition at line 46 of file chan_audiosocket.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_AUDIOSOCKET_CODEC 

Definition at line 168 of file chan_audiosocket.c.

168 {
169 OPT_AUDIOSOCKET_CODEC = (1 << 0),
170};
@ OPT_AUDIOSOCKET_CODEC

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_AUDIOSOCKET_CODEC 
OPT_ARG_ARRAY_SIZE 

Definition at line 172 of file chan_audiosocket.c.

172 {
173 OPT_ARG_AUDIOSOCKET_CODEC = (1 << 0),
175};
@ OPT_ARG_AUDIOSOCKET_CODEC
@ OPT_ARG_ARRAY_SIZE

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 346 of file chan_audiosocket.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 346 of file chan_audiosocket.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 346 of file chan_audiosocket.c.

◆ audiosocket_call()

static int audiosocket_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
)
static

Function called when we should actually call the destination.

Definition at line 142 of file chan_audiosocket.c.

143{
144 struct audiosocket_instance *instance = ast_channel_tech_pvt(ast);
145
147
148 return ast_audiosocket_init(instance->svc, instance->id);
149}
void * ast_channel_tech_pvt(const struct ast_channel *chan)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1269
@ AST_CONTROL_ANSWER
const int ast_audiosocket_init(const int svc, const char *id)
Send the initial message to an AudioSocket server.

References ast_audiosocket_init(), ast_channel_tech_pvt(), AST_CONTROL_ANSWER, ast_queue_control(), audiosocket_instance::id, and audiosocket_instance::svc.

◆ audiosocket_hangup()

static int audiosocket_hangup ( struct ast_channel ast)
static

Function called when we should hang the channel up.

Definition at line 152 of file chan_audiosocket.c.

153{
154 struct audiosocket_instance *instance;
155
156 /* The channel should always be present from the API */
157 instance = ast_channel_tech_pvt(ast);
158 if (instance != NULL && instance->svc > 0) {
159 close(instance->svc);
160 }
161
163 ast_free(instance);
164
165 return 0;
166}
#define ast_free(a)
Definition: astmm.h:180
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
#define NULL
Definition: resample.c:96

References ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_free, NULL, and audiosocket_instance::svc.

◆ audiosocket_read()

static struct ast_frame * audiosocket_read ( struct ast_channel ast)
static

Function called when we should read a frame from the channel.

Definition at line 77 of file chan_audiosocket.c.

78{
79 struct audiosocket_instance *instance;
80 struct ast_frame *frame;
81 int hangup;
82
83
84 /* The channel should always be present from the API */
85 instance = ast_channel_tech_pvt(ast);
86 if (instance == NULL || instance->svc < FD_OUTPUT) {
87 return NULL;
88 }
89
91 if (!frame && !hangup) {
92 ast_log(LOG_ERROR, "Failed to receive frame from AudioSocket server '%s'"
93 " connected to channel '%s'\n", instance->server, ast_channel_name(ast));
94 }
95 return frame;
96}
#define ast_log
Definition: astobj2.c:42
#define FD_OUTPUT
static int hangup(void *data)
Definition: chan_pjsip.c:2520
const char * ast_channel_name(const struct ast_channel *chan)
#define LOG_ERROR
struct ast_frame * ast_audiosocket_receive_frame_with_hangup(const int svc, int *const hangup)
Receive an Asterisk frame from an AudioSocket server.
Data structure associated with a single frame of data.

References ast_audiosocket_receive_frame_with_hangup(), ast_channel_name(), ast_channel_tech_pvt(), ast_log, FD_OUTPUT, hangup(), LOG_ERROR, NULL, audiosocket_instance::server, and audiosocket_instance::svc.

◆ audiosocket_request()

static struct ast_channel * audiosocket_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
)
static

Function called when we should prepare to call the unicast destination.

Definition at line 182 of file chan_audiosocket.c.

185{
186 char *parse;
187 struct audiosocket_instance *instance = NULL;
188 struct ast_sockaddr address;
189 struct ast_channel *chan;
190 struct ast_format_cap *caps = NULL;
191 struct ast_format *fmt = NULL;
192 uuid_t uu;
193 int fd = -1;
195 AST_APP_ARG(destination);
196 AST_APP_ARG(idStr);
198 );
199 struct ast_flags opts = { 0, };
200 char *opt_args[OPT_ARG_ARRAY_SIZE];
201
202 if (ast_strlen_zero(data)) {
203 ast_log(LOG_ERROR, "Destination is required for the 'AudioSocket' channel\n");
204 goto failure;
205 }
206 parse = ast_strdupa(data);
207 AST_NONSTANDARD_APP_ARGS(args, parse, '/');
208
209 if (ast_strlen_zero(args.destination)) {
210 ast_log(LOG_ERROR, "Destination is required for the 'AudioSocket' channel\n");
211 goto failure;
212 }
214 (&address, args.destination, PARSE_PORT_REQUIRE, AST_AF_UNSPEC)) {
215 ast_log(LOG_ERROR, "Destination '%s' could not be parsed\n", args.destination);
216 goto failure;
217 }
218
219 if (ast_strlen_zero(args.idStr)) {
220 ast_log(LOG_ERROR, "UUID is required for the 'AudioSocket' channel\n");
221 goto failure;
222 }
223 if (uuid_parse(args.idStr, uu)) {
224 ast_log(LOG_ERROR, "Failed to parse UUID '%s'\n", args.idStr);
225 goto failure;
226 }
227
228 if (!ast_strlen_zero(args.options)
229 && ast_app_parse_options(audiosocket_options, &opts, opt_args,
230 ast_strdupa(args.options))) {
231 ast_log(LOG_ERROR, "'AudioSocket' channel options '%s' parse error\n",
232 args.options);
233 goto failure;
234 }
235
239 if (!fmt) {
240 ast_log(LOG_ERROR, "Codec '%s' not found for AudioSocket connection to '%s'\n",
241 opt_args[OPT_ARG_AUDIOSOCKET_CODEC], args.destination);
242 goto failure;
243 }
244 } else {
245 fmt = ast_format_cap_get_format(cap, 0);
246 if (!fmt) {
247 ast_log(LOG_ERROR, "No codec available for AudioSocket connection to '%s'\n",
248 args.destination);
249 goto failure;
250 }
251 }
252
254 if (!caps) {
255 goto failure;
256 }
257
258 instance = ast_calloc(1, sizeof(*instance));
259 if (!instance) {
260 ast_log(LOG_ERROR, "Failed to allocate AudioSocket channel pvt\n");
261 goto failure;
262 }
263 ast_copy_string(instance->id, args.idStr, sizeof(instance->id));
264
265 if ((fd = ast_audiosocket_connect(args.destination, NULL)) < 0) {
266 goto failure;
267 }
268 /* Make a copy of the server address for display in error messages. */
269 ast_copy_string(instance->server, args.destination, sizeof(instance->server));
270 instance->svc = fd;
271
272 chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
273 requestor, 0, "AudioSocket/%s-%s", args.destination, args.idStr);
274 if (!chan) {
275 goto failure;
276 }
277 ast_channel_set_fd(chan, 0, fd);
278
280
281 ast_format_cap_append(caps, fmt, 0);
287
288 ast_channel_tech_pvt_set(chan, instance);
289
290 pbx_builtin_setvar_helper(chan, "AUDIOSOCKET_UUID", args.idStr);
291 pbx_builtin_setvar_helper(chan, "AUDIOSOCKET_SERVICE", args.destination);
292
293 ast_channel_unlock(chan);
294
295 ao2_ref(fmt, -1);
296 ao2_ref(caps, -1);
297 return chan;
298
299failure:
300 *cause = AST_CAUSE_FAILURE;
301 ao2_cleanup(fmt);
302 ao2_cleanup(caps);
303 if (instance != NULL) {
304 ast_free(instance);
305 if (fd >= 0) {
306 close(fd);
307 }
308 }
309
310 return NULL;
311}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define AST_CAUSE_FAILURE
Definition: causes.h:150
static const struct ast_app_option audiosocket_options[128]
static struct ast_channel_tech audiosocket_channel_tech
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1299
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2395
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_DOWN
Definition: channelstate.h:36
char * address
Definition: f2c.h:59
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
Definition: format_cache.h:278
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
@ PARSE_PORT_REQUIRE
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
Definition: netsock2.c:337
@ AST_AF_UNSPEC
Definition: netsock2.h:54
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
const int ast_audiosocket_connect(const char *server, struct ast_channel *chan)
Send the initial message to an AudioSocket server.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Main Channel structure associated with a channel.
Structure used to handle boolean flags.
Definition: utils.h:199
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
Socket address structure.
Definition: netsock2.h:97
const char * args
static struct test_options options
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ao2_cleanup, ao2_ref, args, AST_AF_UNSPEC, AST_APP_ARG, ast_app_parse_options(), ast_audiosocket_connect(), ast_calloc, AST_CAUSE_FAILURE, ast_channel_alloc, ast_channel_nativeformats_set(), ast_channel_set_fd(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_format_cache_get, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_free, ast_log, AST_NONSTANDARD_APP_ARGS, ast_sockaddr_resolve_first_af(), AST_STATE_DOWN, ast_strdupa, ast_strlen_zero(), ast_test_flag, audiosocket_channel_tech, audiosocket_options, audiosocket_instance::id, LOG_ERROR, NULL, OPT_ARG_ARRAY_SIZE, OPT_ARG_AUDIOSOCKET_CODEC, OPT_AUDIOSOCKET_CODEC, options, PARSE_PORT_REQUIRE, pbx_builtin_setvar_helper(), audiosocket_instance::server, and audiosocket_instance::svc.

◆ audiosocket_send_dtmf()

static int audiosocket_send_dtmf ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Function called when we should write a DTMF frame to the channel.

Definition at line 118 of file chan_audiosocket.c.

119{
120 struct audiosocket_instance *instance;
121 struct ast_frame f;
122
123 /* The channel should always be present from the API */
124 instance = ast_channel_tech_pvt(ast);
125 if (instance == NULL || instance->svc < 1) {
126 return -1;
127 }
128
129 f.frametype = AST_FRAME_DTMF;
130 f.subclass.integer = digit;
131 f.len = duration;
132
133 if (ast_audiosocket_send_frame(instance->svc, &f)) {
134 ast_log(LOG_ERROR, "Failed to forward DTMF frame from channel '%s' to AudioSocket server '%s'\n",
135 ast_channel_name(ast), instance->server);
136 return -1;
137 }
138 return 0;
139}
char digit
#define AST_FRAME_DTMF
const int ast_audiosocket_send_frame(const int svc, const struct ast_frame *f)
Send an Asterisk audio frame to an AudioSocket server.

References ast_audiosocket_send_frame(), ast_channel_name(), ast_channel_tech_pvt(), AST_FRAME_DTMF, ast_log, digit, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::len, LOG_ERROR, NULL, audiosocket_instance::server, ast_frame::subclass, and audiosocket_instance::svc.

◆ audiosocket_write()

static int audiosocket_write ( struct ast_channel ast,
struct ast_frame f 
)
static

Function called when we should write a frame to the channel.

Definition at line 99 of file chan_audiosocket.c.

100{
101 struct audiosocket_instance *instance;
102
103 /* The channel should always be present from the API */
104 instance = ast_channel_tech_pvt(ast);
105 if (instance == NULL || instance->svc < 1) {
106 return -1;
107 }
108
109 if (ast_audiosocket_send_frame(instance->svc, f)) {
110 ast_log(LOG_ERROR, "Failed to forward frame from channel '%s' to AudioSocket server '%s'\n",
111 ast_channel_name(ast), instance->server);
112 return -1;
113 }
114 return 0;
115}

References ast_audiosocket_send_frame(), ast_channel_name(), ast_channel_tech_pvt(), ast_log, LOG_ERROR, NULL, audiosocket_instance::server, and audiosocket_instance::svc.

◆ load_module()

static int load_module ( void  )
static

Function called when our module is loaded.

Definition at line 324 of file chan_audiosocket.c.

325{
328 }
331 ast_log(LOG_ERROR, "Unable to register channel class AudioSocket");
335 }
336
338}
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:538
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
@ 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
struct ast_format_cap * capabilities
Definition: channel.h:652

References ao2_ref, ast_channel_register(), ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_log, AST_MEDIA_TYPE_UNKNOWN, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, audiosocket_channel_tech, ast_channel_tech::capabilities, LOG_ERROR, and NULL.

◆ unload_module()

static int unload_module ( void  )
static

Function called when our module is unloaded.

Definition at line 314 of file chan_audiosocket.c.

315{
319
320 return 0;
321}
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:569

References ao2_cleanup, ast_channel_unregister(), audiosocket_channel_tech, ast_channel_tech::capabilities, and NULL.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "AudioSocket Channel" , .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_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "res_audiosocket", }
static

Definition at line 346 of file chan_audiosocket.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 346 of file chan_audiosocket.c.

◆ audiosocket_channel_tech

struct ast_channel_tech audiosocket_channel_tech
static

Definition at line 65 of file chan_audiosocket.c.

Referenced by audiosocket_request(), load_module(), and unload_module().

◆ audiosocket_instance

◆ audiosocket_options

const struct ast_app_option audiosocket_options[128] = { [ 'c' ] = { .flag = OPT_AUDIOSOCKET_CODEC , .arg_index = OPT_ARG_AUDIOSOCKET_CODEC + 1 }, }
static

Definition at line 179 of file chan_audiosocket.c.

Referenced by audiosocket_request().