Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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.
 
static int audiosocket_hangup (struct ast_channel *ast)
 Function called when we should hang the channel up.
 
static struct ast_frameaudiosocket_read (struct ast_channel *ast)
 Function called when we should read a frame from the channel.
 
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.
 
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.
 
static int audiosocket_write (struct ast_channel *ast, struct ast_frame *f)
 Function called when we should write a frame to the channel.
 
static int load_module (void)
 Function called when our module is loaded.
 
static int unload_module (void)
 Function called when our module is unloaded.
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "AudioSocket Channel" , .key = ASTERISK_GPL_KEY , .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:1288
@ 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)
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:2416
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
Definition channel.h:2983
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_DOWN
char * address
Definition f2c.h:59
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
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
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 struct @519 args
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:220
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
static struct test_options options
#define ast_test_flag(p, flag)
Definition utils.h:64

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:539
@ 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:570

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 = ASTERISK_GPL_KEY , .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.

65 {
66 .type = "AudioSocket",
67 .description = "AudioSocket Channel Driver",
68 .requester = audiosocket_request,
69 .call = audiosocket_call,
70 .hangup = audiosocket_hangup,
71 .read = audiosocket_read,
72 .write = audiosocket_write,
73 .send_digit_end = audiosocket_send_dtmf,
74};
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.
static int audiosocket_hangup(struct ast_channel *ast)
Function called when we should hang the channel up.
static int audiosocket_write(struct ast_channel *ast, struct ast_frame *f)
Function called when we should write a frame to the channel.
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)
Function called when we should prepare to call the unicast destination.
static int audiosocket_call(struct ast_channel *ast, const char *dest, int timeout)
Function called when we should actually call the destination.
static struct ast_frame * audiosocket_read(struct ast_channel *ast)
Function called when we should read a frame from the channel.

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().