00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00033
00034 #include <fcntl.h>
00035 #include <sys/signal.h>
00036
00037 #include "asterisk/lock.h"
00038 #include "asterisk/channel.h"
00039 #include "asterisk/config.h"
00040 #include "asterisk/module.h"
00041 #include "asterisk/pbx.h"
00042 #include "asterisk/sched.h"
00043 #include "asterisk/io.h"
00044 #include "asterisk/acl.h"
00045 #include "asterisk/callerid.h"
00046 #include "asterisk/file.h"
00047 #include "asterisk/cli.h"
00048 #include "asterisk/app.h"
00049 #include "asterisk/rtp_engine.h"
00050 #include "asterisk/causes.h"
00051
00052 static const char tdesc[] = "Multicast RTP Paging Channel Driver";
00053
00054
00055 static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
00056 static int multicast_rtp_call(struct ast_channel *ast, char *dest, int timeout);
00057 static int multicast_rtp_hangup(struct ast_channel *ast);
00058 static struct ast_frame *multicast_rtp_read(struct ast_channel *ast);
00059 static int multicast_rtp_write(struct ast_channel *ast, struct ast_frame *f);
00060
00061
00062 static const struct ast_channel_tech multicast_rtp_tech = {
00063 .type = "MulticastRTP",
00064 .description = tdesc,
00065 .capabilities = -1,
00066 .requester = multicast_rtp_request,
00067 .call = multicast_rtp_call,
00068 .hangup = multicast_rtp_hangup,
00069 .read = multicast_rtp_read,
00070 .write = multicast_rtp_write,
00071 };
00072
00073
00074 static struct ast_frame *multicast_rtp_read(struct ast_channel *ast)
00075 {
00076 return &ast_null_frame;
00077 }
00078
00079
00080 static int multicast_rtp_write(struct ast_channel *ast, struct ast_frame *f)
00081 {
00082 struct ast_rtp_instance *instance = ast->tech_pvt;
00083
00084 return ast_rtp_instance_write(instance, f);
00085 }
00086
00087
00088 static int multicast_rtp_call(struct ast_channel *ast, char *dest, int timeout)
00089 {
00090 struct ast_rtp_instance *instance = ast->tech_pvt;
00091
00092 ast_queue_control(ast, AST_CONTROL_ANSWER);
00093
00094 return ast_rtp_instance_activate(instance);
00095 }
00096
00097
00098 static int multicast_rtp_hangup(struct ast_channel *ast)
00099 {
00100 struct ast_rtp_instance *instance = ast->tech_pvt;
00101
00102 ast_rtp_instance_destroy(instance);
00103
00104 ast->tech_pvt = NULL;
00105
00106 return 0;
00107 }
00108
00109
00110 static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
00111 {
00112 char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control;
00113 struct ast_rtp_instance *instance;
00114 struct ast_sockaddr control_address;
00115 struct ast_sockaddr destination_address;
00116 struct ast_channel *chan;
00117 format_t fmt = ast_best_codec(format);
00118
00119 ast_sockaddr_setnull(&control_address);
00120
00121
00122 if (ast_strlen_zero(multicast_type)) {
00123 goto failure;
00124 }
00125
00126 if (!(destination = strchr(tmp, '/'))) {
00127 goto failure;
00128 }
00129 *destination++ = '\0';
00130
00131 if ((control = strchr(destination, '/'))) {
00132 *control++ = '\0';
00133 if (!ast_sockaddr_parse(&control_address, control,
00134 PARSE_PORT_REQUIRE)) {
00135 goto failure;
00136 }
00137 }
00138
00139 if (!ast_sockaddr_parse(&destination_address, destination,
00140 PARSE_PORT_REQUIRE)) {
00141 goto failure;
00142 }
00143
00144 if (!(instance = ast_rtp_instance_new("multicast", NULL, &control_address, multicast_type))) {
00145 goto failure;
00146 }
00147
00148 if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", requestor ? requestor->linkedid : "", 0, "MulticastRTP/%p", instance))) {
00149 ast_rtp_instance_destroy(instance);
00150 goto failure;
00151 }
00152
00153 ast_rtp_instance_set_remote_address(instance, &destination_address);
00154
00155 chan->tech = &multicast_rtp_tech;
00156 chan->nativeformats = fmt;
00157 chan->writeformat = fmt;
00158 chan->readformat = fmt;
00159 chan->rawwriteformat = fmt;
00160 chan->rawreadformat = fmt;
00161 chan->tech_pvt = instance;
00162
00163 return chan;
00164
00165 failure:
00166 *cause = AST_CAUSE_FAILURE;
00167 return NULL;
00168 }
00169
00170
00171 static int load_module(void)
00172 {
00173 if (ast_channel_register(&multicast_rtp_tech)) {
00174 ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
00175 return AST_MODULE_LOAD_DECLINE;
00176 }
00177
00178 return AST_MODULE_LOAD_SUCCESS;
00179 }
00180
00181
00182 static int unload_module(void)
00183 {
00184 ast_channel_unregister(&multicast_rtp_tech);
00185
00186 return 0;
00187 }
00188
00189 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Multicast RTP Paging Channel",
00190 .load = load_module,
00191 .unload = unload_module,
00192 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
00193 );