Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
app_audiosocket.c File Reference

AudioSocket application – transmit and receive audio through a TCP socket. More...

#include "asterisk.h"
#include "errno.h"
#include <uuid/uuid.h>
#include "asterisk/file.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/res_audiosocket.h"
#include "asterisk/utils.h"
#include "asterisk/format_cache.h"
Include dependency graph for app_audiosocket.c:

Go to the source code of this file.

Macros

#define AST_MODULE   "app_audiosocket"
 
#define AUDIOSOCKET_CONFIG   "audiosocket.conf"
 
#define MAX_CONNECT_TIMEOUT_MSEC   2000
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int audiosocket_exec (struct ast_channel *chan, const char *data)
 
static int audiosocket_run (struct ast_channel *chan, const char *id, const int svc)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = "app_audiosocket" , .flags = AST_MODFLAG_LOAD_ORDER , .description = "AudioSocket Application" , .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 char app [] = "AudioSocket"
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

AudioSocket application – transmit and receive audio through a TCP socket.

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

Definition in file app_audiosocket.c.

Macro Definition Documentation

◆ AST_MODULE

#define AST_MODULE   "app_audiosocket"

◆ AUDIOSOCKET_CONFIG

#define AUDIOSOCKET_CONFIG   "audiosocket.conf"

Definition at line 46 of file app_audiosocket.c.

◆ MAX_CONNECT_TIMEOUT_MSEC

#define MAX_CONNECT_TIMEOUT_MSEC   2000

Definition at line 47 of file app_audiosocket.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 240 of file app_audiosocket.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 240 of file app_audiosocket.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 240 of file app_audiosocket.c.

◆ audiosocket_exec()

static int audiosocket_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 74 of file app_audiosocket.c.

References ao2_bump, ao2_ref, args, AST_APP_ARG, ast_audiosocket_connect(), ast_channel_name(), ast_channel_readformat(), ast_channel_writeformat(), AST_DECLARE_APP_ARGS, ast_format_slin, ast_log, ast_set_read_format(), ast_set_write_format(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, audiosocket_run(), LOG_ERROR, and parse().

Referenced by load_module().

75 {
76  char *parse;
77  struct ast_format *readFormat, *writeFormat;
78  const char *chanName;
79  int res;
80 
82  AST_APP_ARG(idStr);
83  AST_APP_ARG(server);
84  );
85 
86  int s = 0;
87  uuid_t uu;
88 
89 
90  chanName = ast_channel_name(chan);
91 
92  /* Parse and validate arguments */
93  parse = ast_strdupa(data);
95  if (ast_strlen_zero(args.idStr)) {
96  ast_log(LOG_ERROR, "UUID is required\n");
97  return -1;
98  }
99  if (uuid_parse(args.idStr, uu)) {
100  ast_log(LOG_ERROR, "Failed to parse UUID '%s'\n", args.idStr);
101  return -1;
102  }
103  if ((s = ast_audiosocket_connect(args.server, chan)) < 0) {
104  /* The res module will already output a log message, so another is not needed */
105  return -1;
106  }
107 
108  writeFormat = ao2_bump(ast_channel_writeformat(chan));
109  readFormat = ao2_bump(ast_channel_readformat(chan));
110 
112  ast_log(LOG_ERROR, "Failed to set write format to SLINEAR for channel %s\n", chanName);
113  ao2_ref(writeFormat, -1);
114  ao2_ref(readFormat, -1);
115  close(s);
116  return -1;
117  }
119  ast_log(LOG_ERROR, "Failed to set read format to SLINEAR for channel %s\n", chanName);
120 
121  /* Attempt to restore previous write format even though it is likely to
122  * fail, since setting the read format did.
123  */
124  if (ast_set_write_format(chan, writeFormat)) {
125  ast_log(LOG_ERROR, "Failed to restore write format for channel %s\n", chanName);
126  }
127  ao2_ref(writeFormat, -1);
128  ao2_ref(readFormat, -1);
129  close(s);
130  return -1;
131  }
132 
133  res = audiosocket_run(chan, args.idStr, s);
134  /* On non-zero return, report failure */
135  if (res) {
136  /* Restore previous formats and close the connection */
137  if (ast_set_write_format(chan, writeFormat)) {
138  ast_log(LOG_ERROR, "Failed to restore write format for channel %s\n", chanName);
139  }
140  if (ast_set_read_format(chan, readFormat)) {
141  ast_log(LOG_ERROR, "Failed to restore read format for channel %s\n", chanName);
142  }
143  ao2_ref(writeFormat, -1);
144  ao2_ref(readFormat, -1);
145  close(s);
146  return res;
147  }
148  close(s);
149 
150  if (ast_set_write_format(chan, writeFormat)) {
151  ast_log(LOG_ERROR, "Failed to restore write format for channel %s\n", chanName);
152  }
153  if (ast_set_read_format(chan, readFormat)) {
154  ast_log(LOG_ERROR, "Failed to restore read format for channel %s\n", chanName);
155  }
156  ao2_ref(writeFormat, -1);
157  ao2_ref(readFormat, -1);
158 
159  return 0;
160 }
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition of a media format.
Definition: format.c:43
const char * args
const int ast_audiosocket_connect(const char *server, struct ast_channel *chan)
Send the initial message to an AudioSocket server.
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
#define LOG_ERROR
Definition: logger.h:285
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
static int audiosocket_run(struct ast_channel *chan, const char *id, const int svc)
#define AST_APP_ARG(name)
Define an application argument.

◆ audiosocket_run()

static int audiosocket_run ( struct ast_channel chan,
const char *  id,
const int  svc 
)
static

Definition at line 162 of file app_audiosocket.c.

References ast_audiosocket_init(), ast_audiosocket_receive_frame(), ast_audiosocket_send_frame(), ast_channel_name(), AST_FRAME_VOICE, ast_frfree, ast_log, ast_read(), AST_STATE_UP, ast_waitfor_nandfds(), ast_write(), ast_frame::frametype, LOG_ERROR, LOG_WARNING, and NULL.

Referenced by audiosocket_exec().

163 {
164  const char *chanName;
165  struct ast_channel *targetChan;
166  int ms = 0;
167  int outfd = -1;
168  struct ast_frame *f;
169 
170  if (!chan || ast_channel_state(chan) != AST_STATE_UP) {
171  ast_log(LOG_ERROR, "Channel is %s\n", chan ? "not answered" : "missing");
172  return -1;
173  }
174 
175  if (ast_audiosocket_init(svc, id)) {
176  ast_log(LOG_ERROR, "Failed to intialize AudioSocket\n");
177  return -1;
178  }
179 
180  chanName = ast_channel_name(chan);
181 
182  while (1) {
183 
184  targetChan = ast_waitfor_nandfds(&chan, 1, &svc, 1, NULL, &outfd, &ms);
185  if (targetChan) {
186  f = ast_read(chan);
187  if (!f) {
188  return -1;
189  }
190 
191  if (f->frametype == AST_FRAME_VOICE) {
192  /* Send audio frame to audiosocket */
193  if (ast_audiosocket_send_frame(svc, f)) {
194  ast_log(LOG_ERROR, "Failed to forward channel frame from %s to AudioSocket\n",
195  chanName);
196  ast_frfree(f);
197  return -1;
198  }
199  }
200  ast_frfree(f);
201  }
202 
203  if (outfd >= 0) {
205  if (!f) {
206  ast_log(LOG_ERROR, "Failed to receive frame from AudioSocket message for"
207  "channel %s\n", chanName);
208  return -1;
209  }
210  if (ast_write(chan, f)) {
211  ast_log(LOG_WARNING, "Failed to forward frame to channel %s\n", chanName);
212  ast_frfree(f);
213  return -1;
214  }
215  ast_frfree(f);
216  }
217  }
218  return 0;
219 }
Main Channel structure associated with a channel.
#define LOG_WARNING
Definition: logger.h:274
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition: channel.c:2997
#define ast_log
Definition: astobj2.c:42
const int ast_audiosocket_init(const int svc, const char *id)
Send the initial message to an AudioSocket server.
#define LOG_ERROR
Definition: logger.h:285
const int ast_audiosocket_send_frame(const int svc, const struct ast_frame *f)
Send an Asterisk audio frame to an AudioSocket server.
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5189
struct ast_frame * ast_audiosocket_receive_frame(const int svc)
Receive an Asterisk frame from an AudioSocket server.
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
Data structure associated with a single frame of data.
enum ast_frame_type frametype

◆ load_module()

static int load_module ( void  )
static

Definition at line 226 of file app_audiosocket.c.

References app, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_EXTENDED, ast_register_application_xml, ASTERISK_GPL_KEY, audiosocket_exec(), and unload_module().

227 {
229 }
static const char app[]
static int audiosocket_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 221 of file app_audiosocket.c.

References app, and ast_unregister_application().

Referenced by load_module().

222 {
224 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static const char app[]

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = "app_audiosocket" , .flags = AST_MODFLAG_LOAD_ORDER , .description = "AudioSocket Application" , .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 240 of file app_audiosocket.c.

◆ app

const char app[] = "AudioSocket"
static

Definition at line 70 of file app_audiosocket.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 240 of file app_audiosocket.c.