Asterisk - The Open Source Telephony Project  18.5.0
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_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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 45 of file chan_audiosocket.c.

Referenced by audiosocket_read().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_AUDIOSOCKET_CODEC 

Definition at line 125 of file chan_audiosocket.c.

125  {
126  OPT_AUDIOSOCKET_CODEC = (1 << 0),
127 };

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_AUDIOSOCKET_CODEC 
OPT_ARG_ARRAY_SIZE 

Definition at line 129 of file chan_audiosocket.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 301 of file chan_audiosocket.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 301 of file chan_audiosocket.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 301 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 99 of file chan_audiosocket.c.

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

100 {
101  struct audiosocket_instance *instance = ast_channel_tech_pvt(ast);
102 
104 
105  return ast_audiosocket_init(instance->svc, instance->id);
106 }
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
void * ast_channel_tech_pvt(const struct ast_channel *chan)
const int ast_audiosocket_init(const int svc, const char *id)
Send the initial message to an AudioSocket server.

◆ audiosocket_hangup()

static int audiosocket_hangup ( struct ast_channel ast)
static

Function called when we should hang the channel up.

Definition at line 109 of file chan_audiosocket.c.

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

110 {
111  struct audiosocket_instance *instance;
112 
113  /* The channel should always be present from the API */
114  instance = ast_channel_tech_pvt(ast);
115  if (instance != NULL && instance->svc > 0) {
116  close(instance->svc);
117  }
118 
120  ast_free(instance);
121 
122  return 0;
123 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ 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 73 of file chan_audiosocket.c.

References ast_audiosocket_receive_frame(), ast_channel_tech_pvt(), FD_OUTPUT, NULL, and audiosocket_instance::svc.

74 {
75  struct audiosocket_instance *instance;
76 
77  /* The channel should always be present from the API */
78  instance = ast_channel_tech_pvt(ast);
79  if (instance == NULL || instance->svc < FD_OUTPUT) {
80  return NULL;
81  }
82  return ast_audiosocket_receive_frame(instance->svc);
83 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define FD_OUTPUT
struct ast_frame * ast_audiosocket_receive_frame(const int svc)
Receive an Asterisk frame from an AudioSocket server.

◆ 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 139 of file chan_audiosocket.c.

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_options, audiosocket_instance::id, LOG_ERROR, NULL, OPT_ARG_ARRAY_SIZE, OPT_ARG_AUDIOSOCKET_CODEC, OPT_AUDIOSOCKET_CODEC, options, parse(), PARSE_PORT_REQUIRE, pbx_builtin_setvar_helper(), and audiosocket_instance::svc.

142 {
143  char *parse;
144  struct audiosocket_instance *instance = NULL;
145  struct ast_sockaddr address;
146  struct ast_channel *chan;
147  struct ast_format_cap *caps = NULL;
148  struct ast_format *fmt = NULL;
149  uuid_t uu;
150  int fd = -1;
152  AST_APP_ARG(destination);
153  AST_APP_ARG(idStr);
155  );
156  struct ast_flags opts = { 0, };
157  char *opt_args[OPT_ARG_ARRAY_SIZE];
158 
159  if (ast_strlen_zero(data)) {
160  ast_log(LOG_ERROR, "Destination is required for the 'AudioSocket' channel\n");
161  goto failure;
162  }
163  parse = ast_strdupa(data);
164  AST_NONSTANDARD_APP_ARGS(args, parse, '/');
165 
166  if (ast_strlen_zero(args.destination)) {
167  ast_log(LOG_ERROR, "Destination is required for the 'AudioSocket' channel\n");
168  goto failure;
169  }
171  (&address, args.destination, PARSE_PORT_REQUIRE, AST_AF_UNSPEC)) {
172  ast_log(LOG_ERROR, "Destination '%s' could not be parsed\n", args.destination);
173  goto failure;
174  }
175 
176  if (ast_strlen_zero(args.idStr)) {
177  ast_log(LOG_ERROR, "UUID is required for the 'AudioSocket' channel\n");
178  goto failure;
179  }
180  if (uuid_parse(args.idStr, uu)) {
181  ast_log(LOG_ERROR, "Failed to parse UUID '%s'\n", args.idStr);
182  goto failure;
183  }
184 
185  if (!ast_strlen_zero(args.options)
186  && ast_app_parse_options(audiosocket_options, &opts, opt_args,
187  ast_strdupa(args.options))) {
188  ast_log(LOG_ERROR, "'AudioSocket' channel options '%s' parse error\n",
189  args.options);
190  goto failure;
191  }
192 
195  fmt = ast_format_cache_get(opt_args[OPT_ARG_AUDIOSOCKET_CODEC]);
196  if (!fmt) {
197  ast_log(LOG_ERROR, "Codec '%s' not found for AudioSocket connection to '%s'\n",
198  opt_args[OPT_ARG_AUDIOSOCKET_CODEC], args.destination);
199  goto failure;
200  }
201  } else {
202  fmt = ast_format_cap_get_format(cap, 0);
203  if (!fmt) {
204  ast_log(LOG_ERROR, "No codec available for AudioSocket connection to '%s'\n",
205  args.destination);
206  goto failure;
207  }
208  }
209 
211  if (!caps) {
212  goto failure;
213  }
214 
215  instance = ast_calloc(1, sizeof(*instance));
216  if (!instance) {
217  ast_log(LOG_ERROR, "Failed to allocate AudioSocket channel pvt\n");
218  goto failure;
219  }
220  ast_copy_string(instance->id, args.idStr, sizeof(instance->id));
221 
222  if ((fd = ast_audiosocket_connect(args.destination, NULL)) < 0) {
223  goto failure;
224  }
225  instance->svc = fd;
226 
227  chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids,
228  requestor, 0, "AudioSocket/%s-%s", args.destination, args.idStr);
229  if (!chan) {
230  goto failure;
231  }
232  ast_channel_set_fd(chan, 0, fd);
233 
235 
236  ast_format_cap_append(caps, fmt, 0);
237  ast_channel_nativeformats_set(chan, caps);
238  ast_channel_set_writeformat(chan, fmt);
240  ast_channel_set_readformat(chan, fmt);
242 
243  ast_channel_tech_pvt_set(chan, instance);
244 
245  pbx_builtin_setvar_helper(chan, "AUDIOSOCKET_UUID", args.idStr);
246  pbx_builtin_setvar_helper(chan, "AUDIOSOCKET_SERVICE", args.destination);
247 
248  ast_channel_unlock(chan);
249 
250  ao2_ref(fmt, -1);
251  ao2_ref(caps, -1);
252  return chan;
253 
254 failure:
255  *cause = AST_CAUSE_FAILURE;
256  ao2_cleanup(fmt);
257  ao2_cleanup(caps);
258  if (instance != NULL) {
259  ast_free(instance);
260  if (fd >= 0) {
261  close(fd);
262  }
263  }
264 
265  return NULL;
266 }
Main Channel structure associated with a channel.
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * address
Definition: f2c.h:59
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
static const struct ast_app_option audiosocket_options[128]
static struct ast_channel_tech audiosocket_channel_tech
Definition of a media format.
Definition: format.c:43
const char * args
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
const int ast_audiosocket_connect(const char *server, struct ast_channel *chan)
Send the initial message to an AudioSocket server.
#define ast_format_cache_get(name)
Definition: format_cache.h:286
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
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
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
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:2906
#define AST_CAUSE_FAILURE
Definition: causes.h:149
#define LOG_ERROR
Definition: logger.h:285
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Structure used to handle boolean flags.
Definition: utils.h:199
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
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...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct test_options options
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
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 86 of file chan_audiosocket.c.

References ast_audiosocket_send_frame(), ast_channel_tech_pvt(), NULL, and audiosocket_instance::svc.

87 {
88  struct audiosocket_instance *instance;
89 
90  /* The channel should always be present from the API */
91  instance = ast_channel_tech_pvt(ast);
92  if (instance == NULL || instance->svc < 1) {
93  return -1;
94  }
95  return ast_audiosocket_send_frame(instance->svc, f);
96 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
const int ast_audiosocket_send_frame(const int svc, const struct ast_frame *f)
Send an Asterisk audio frame to an AudioSocket server.

◆ load_module()

static int load_module ( void  )
static

Function called when our module is loaded.

Definition at line 279 of file chan_audiosocket.c.

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_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_EXTENDED, ASTERISK_GPL_KEY, ast_channel_tech::capabilities, LOG_ERROR, NULL, and unload_module().

280 {
283  }
286  ast_log(LOG_ERROR, "Unable to register channel class AudioSocket");
290  }
291 
293 }
static struct ast_channel_tech audiosocket_channel_tech
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
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
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define LOG_ERROR
Definition: logger.h:285
struct ast_format_cap * capabilities
Definition: channel.h:633
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ unload_module()

static int unload_module ( void  )
static

Function called when our module is unloaded.

Definition at line 269 of file chan_audiosocket.c.

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

Referenced by load_module().

270 {
274 
275  return 0;
276 }
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
static struct ast_channel_tech audiosocket_channel_tech
#define NULL
Definition: resample.c:96
struct ast_format_cap * capabilities
Definition: channel.h:633
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 301 of file chan_audiosocket.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 301 of file chan_audiosocket.c.

◆ audiosocket_channel_tech

struct ast_channel_tech audiosocket_channel_tech
static

Definition at line 62 of file chan_audiosocket.c.

◆ 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 136 of file chan_audiosocket.c.

Referenced by audiosocket_request().