Asterisk - The Open Source Telephony Project  18.5.0
chan_bridge_media.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013 Digium, Inc.
5  *
6  * Jonathan Rose <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \brief Bridge Media Channels driver
22  *
23  * \author Jonathan Rose <[email protected]>
24  * \author Richard Mudgett <[email protected]>
25  *
26  * \brief Bridge Media Channels
27  *
28  * \ingroup channel_drivers
29  */
30 
31 /*** MODULEINFO
32  <support_level>core</support_level>
33  ***/
34 
35 #include "asterisk.h"
36 
37 #include "asterisk/channel.h"
38 #include "asterisk/bridge.h"
39 #include "asterisk/core_unreal.h"
40 #include "asterisk/module.h"
41 
42 static int media_call(struct ast_channel *chan, const char *addr, int timeout)
43 {
44  /* ast_call() will fail unconditionally against channels provided by this driver */
45  return -1;
46 }
47 
48 static int media_hangup(struct ast_channel *ast)
49 {
50  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
51  int res;
52 
53  if (!p) {
54  return -1;
55  }
56 
57  /* Give the pvt a ref to fulfill calling requirements. */
58  ao2_ref(p, +1);
59  res = ast_unreal_hangup(p, ast);
60  ao2_ref(p, -1);
61 
62  return res;
63 }
64 
65 static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap,
66  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
67 
68 static struct ast_channel *record_request(const char *type, struct ast_format_cap *cap,
69  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
70 
72  .type = "Announcer",
73  .description = "Bridge Media Announcing Channel Driver",
74  .requester = announce_request,
75  .call = media_call,
76  .hangup = media_hangup,
77 
78  .send_digit_begin = ast_unreal_digit_begin,
79  .send_digit_end = ast_unreal_digit_end,
80  .read = ast_unreal_read,
81  .write = ast_unreal_write,
82  .write_video = ast_unreal_write,
83  .exception = ast_unreal_read,
84  .indicate = ast_unreal_indicate,
85  .fixup = ast_unreal_fixup,
86  .send_html = ast_unreal_sendhtml,
87  .send_text = ast_unreal_sendtext,
88  .queryoption = ast_unreal_queryoption,
89  .setoption = ast_unreal_setoption,
90  .properties = AST_CHAN_TP_INTERNAL,
91 };
92 
93 static struct ast_channel_tech record_tech = {
94  .type = "Recorder",
95  .description = "Bridge Media Recording Channel Driver",
96  .requester = record_request,
97  .call = media_call,
98  .hangup = media_hangup,
99 
100  .send_digit_begin = ast_unreal_digit_begin,
101  .send_digit_end = ast_unreal_digit_end,
102  .read = ast_unreal_read,
103  .write = ast_unreal_write,
104  .write_video = ast_unreal_write,
105  .exception = ast_unreal_read,
106  .indicate = ast_unreal_indicate,
107  .fixup = ast_unreal_fixup,
108  .send_html = ast_unreal_sendhtml,
109  .send_text = ast_unreal_sendtext,
110  .queryoption = ast_unreal_queryoption,
111  .setoption = ast_unreal_setoption,
112  .properties = AST_CHAN_TP_INTERNAL,
113 };
114 
115 static struct ast_channel *media_request_helper(struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids,
116  const struct ast_channel *requestor, const char *data, struct ast_channel_tech *tech, const char *role)
117 {
118  struct ast_channel *chan;
120 
121  RAII_VAR(struct ast_unreal_pvt *, pvt, NULL, ao2_cleanup);
122 
123  if (!(pvt = ast_unreal_alloc(sizeof(*pvt), ast_unreal_destructor, cap))) {
124  return NULL;
125  }
126 
127  ast_copy_string(pvt->name, data, sizeof(pvt->name));
128 
130 
132 
133  chan = ast_unreal_new_channels(pvt, tech,
134  AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, callid);
135  if (!chan) {
136  return NULL;
137  }
138 
139  ast_answer(pvt->owner);
140  ast_answer(pvt->chan);
141 
142  if (ast_channel_add_bridge_role(pvt->chan, role)) {
143  ast_hangup(chan);
144  return NULL;
145  }
146 
147  return chan;
148 }
149 
150 static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap,
151  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
152 {
153  return media_request_helper(cap, assignedids, requestor, data, &announce_tech, "announcer");
154 }
155 
156 static struct ast_channel *record_request(const char *type, struct ast_format_cap *cap,
157  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
158 {
159  return media_request_helper(cap, assignedids, requestor, data, &record_tech, "recorder");
160 }
161 
162 static void cleanup_capabilities(void)
163 {
164  if (announce_tech.capabilities) {
165  ao2_ref(announce_tech.capabilities, -1);
166  announce_tech.capabilities = NULL;
167  }
168 
169  if (record_tech.capabilities) {
170  ao2_ref(record_tech.capabilities, -1);
171  record_tech.capabilities = NULL;
172  }
173 }
174 
175 static int unload_module(void)
176 {
177  ast_channel_unregister(&announce_tech);
178  ast_channel_unregister(&record_tech);
180  return 0;
181 }
182 
183 static int load_module(void)
184 {
186  if (!announce_tech.capabilities) {
188  }
189 
191  if (!record_tech.capabilities) {
193  }
194 
197 
198  if (ast_channel_register(&announce_tech)) {
199  ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
200  announce_tech.type, announce_tech.description);
203  }
204 
205  if (ast_channel_register(&record_tech)) {
206  ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
207  record_tech.type, record_tech.description);
210  }
211 
213 }
214 
215 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Bridge Media Channel Driver",
216  .support_level = AST_MODULE_SUPPORT_CORE,
217  .load = load_module,
218  .unload = unload_module,
219 );
static int media_call(struct ast_channel *chan, const char *addr, int timeout)
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
const char *const type
Definition: channel.h:630
Asterisk main include file. File version handling, generic pbx functions.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
#define ast_set_flag(p, flag)
Definition: utils.h:70
static int timeout
Definition: cdr_mysql.c:86
int ast_unreal_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
Definition: core_unreal.c:846
struct ast_unreal_pvt * ast_unreal_alloc(size_t size, ao2_destructor_fn destructor, struct ast_format_cap *cap)
Allocate the base unreal struct for a derivative.
Definition: core_unreal.c:1111
#define AST_UNREAL_NO_OPTIMIZATION
Definition: core_unreal.h:108
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:605
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
unsigned int ast_callid
Definition: logger.h:87
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
struct ast_channel * ast_unreal_new_channels(struct ast_unreal_pvt *p, const struct ast_channel_tech *tech, int semi1_state, int semi2_state, const char *exten, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid)
Create the semi1 and semi2 unreal channels.
Definition: core_unreal.c:1162
int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
Adds a bridge role to a channel.
Definition: bridge_roles.c:317
int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
Definition: core_unreal.c:622
#define NULL
Definition: resample.c:96
const char * data
static int media_hangup(struct ast_channel *ast)
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:1962
int ast_unreal_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: core_unreal.c:369
const struct ast_channel_tech * tech
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
void ast_unreal_destructor(void *vdoomed)
struct ast_unreal_pvt destructor.
Definition: core_unreal.c:1099
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_unreal_setoption(struct ast_channel *chan, int option, void *data, int datalen)
Definition: core_unreal.c:97
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:972
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:629
int ast_unreal_write(struct ast_channel *ast, struct ast_frame *f)
Definition: core_unreal.c:318
#define LOG_ERROR
Definition: logger.h:285
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
int ast_unreal_digit_begin(struct ast_channel *ast, char digit)
Definition: core_unreal.c:779
static struct ast_channel_tech announce_tech
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
struct ast_format_cap * capabilities
Definition: channel.h:633
static struct ast_channel * announce_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)
int ast_unreal_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
Definition: core_unreal.c:801
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ast_frame * ast_unreal_read(struct ast_channel *ast)
Definition: core_unreal.c:313
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
const char *const description
Definition: channel.h:631
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
int ast_unreal_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
Definition: core_unreal.c:166
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ast_channel_tech record_tech
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
static void cleanup_capabilities(void)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Bridging API.
static struct ast_channel * record_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)
Asterisk module definitions.
static int unload_module(void)
int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
Hangup one end (maybe both ends) of an unreal channel derivative.
Definition: core_unreal.c:1018
static struct ast_channel * media_request_helper(struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, struct ast_channel_tech *tech, const char *role)
int ast_unreal_sendtext(struct ast_channel *ast, const char *text)
Definition: core_unreal.c:824
Unreal channel derivative framework.
static int load_module(void)