Thu Sep 7 01:02:51 2017

Asterisk developer's documentation


app_originate.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2008, Roberto Casas.
00005  * Copyright (C) 2008, Digium, Inc.
00006  *
00007  * Roberto Casas <roberto.casas@diaple.com>
00008  * Russell Bryant <russell@digium.com>
00009  *
00010  * See http://www.asterisk.org for more information about
00011  * the Asterisk project. Please do not directly contact
00012  * any of the maintainers of this project for assistance;
00013  * the project provides a web site, mailing lists and IRC
00014  * channels for your use.
00015  *
00016  * This program is free software, distributed under the terms of
00017  * the GNU General Public License Version 2. See the LICENSE file
00018  * at the top of the source tree.
00019  */
00020 
00021 /*!
00022  * \file
00023  * \brief Originate application
00024  *
00025  * \author Roberto Casas <roberto.casas@diaple.com>
00026  * \author Russell Bryant <russell@digium.com>
00027  *
00028  * \ingroup applications
00029  *
00030  * \todo Make a way to be able to set variables (and functions) on the outbound
00031  *       channel, similar to the Variable headers for the AMI Originate, and the
00032  *       Set options for call files.
00033  */
00034 
00035 /*** MODULEINFO
00036    <support_level>core</support_level>
00037  ***/
00038 
00039 #include "asterisk.h"
00040 
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00042 
00043 #include "asterisk/file.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/app.h"
00048 
00049 static const char app_originate[] = "Originate";
00050 
00051 /*** DOCUMENTATION
00052    <application name="Originate" language="en_US">
00053       <synopsis>
00054          Originate a call.
00055       </synopsis>
00056       <syntax>
00057          <parameter name="tech_data" required="true">
00058             <para>Channel technology and data for creating the outbound channel.
00059                       For example, SIP/1234.</para>
00060          </parameter>
00061          <parameter name="type" required="true">
00062             <para>This should be <literal>app</literal> or <literal>exten</literal>, depending on whether the outbound channel should be connected to an application or extension.</para>
00063          </parameter>
00064          <parameter name="arg1" required="true">
00065             <para>If the type is <literal>app</literal>, then this is the application name.  If the type is <literal>exten</literal>, then this is the context that the channel will be sent to.</para>
00066          </parameter>
00067          <parameter name="arg2" required="false">
00068             <para>If the type is <literal>app</literal>, then this is the data passed as arguments to the application.  If the type is <literal>exten</literal>, then this is the extension that the channel will be sent to.</para>
00069          </parameter>
00070          <parameter name="arg3" required="false">
00071             <para>If the type is <literal>exten</literal>, then this is the priority that the channel is sent to.  If the type is <literal>app</literal>, then this parameter is ignored.</para>
00072          </parameter>
00073       </syntax>
00074       <description>
00075       <para>This application originates an outbound call and connects it to a specified extension or application.  This application will block until the outgoing call fails or gets answered.  At that point, this application will exit with the status variable set and dialplan processing will continue.</para>
00076 
00077       <para>This application sets the following channel variable before exiting:</para>
00078       <variablelist>
00079          <variable name="ORIGINATE_STATUS">
00080             <para>This indicates the result of the call origination.</para>
00081             <value name="FAILED"/>
00082             <value name="SUCCESS"/>
00083             <value name="BUSY"/>
00084             <value name="CONGESTION"/>
00085             <value name="HANGUP"/>
00086             <value name="RINGING"/>
00087             <value name="UNKNOWN">
00088             In practice, you should never see this value.  Please report it to the issue tracker if you ever see it.
00089             </value>
00090          </variable>
00091       </variablelist>
00092       </description>
00093    </application>
00094  ***/
00095 
00096 static int originate_exec(struct ast_channel *chan, const char *data)
00097 {
00098    AST_DECLARE_APP_ARGS(args,
00099       AST_APP_ARG(tech_data);
00100       AST_APP_ARG(type);
00101       AST_APP_ARG(arg1);
00102       AST_APP_ARG(arg2);
00103       AST_APP_ARG(arg3);
00104    );
00105    char *parse;
00106    char *chantech, *chandata;
00107    int res = -1;
00108    int outgoing_status = 0;
00109    static const unsigned int timeout = 30;
00110    static const char default_exten[] = "s";
00111 
00112    ast_autoservice_start(chan);
00113 
00114    if (ast_strlen_zero(data)) {
00115       ast_log(LOG_ERROR, "Originate() requires arguments\n");
00116       goto return_cleanup;
00117    }
00118 
00119    parse = ast_strdupa(data);
00120 
00121    AST_STANDARD_APP_ARGS(args, parse);
00122 
00123    if (args.argc < 3) {
00124       ast_log(LOG_ERROR, "Incorrect number of arguments\n");
00125       goto return_cleanup;
00126    }
00127 
00128    chandata = ast_strdupa(args.tech_data);
00129    chantech = strsep(&chandata, "/");
00130 
00131    if (ast_strlen_zero(chandata) || ast_strlen_zero(chantech)) {
00132       ast_log(LOG_ERROR, "Channel Tech/Data invalid: '%s'\n", args.tech_data);
00133       goto return_cleanup;
00134    }
00135 
00136    if (!strcasecmp(args.type, "exten")) {
00137       int priority = 1; /* Initialized in case priority not specified */
00138       const char *exten = args.arg2;
00139 
00140       if (args.argc == 5) {
00141          /* Context/Exten/Priority all specified */
00142          if (sscanf(args.arg3, "%30d", &priority) != 1) {
00143             ast_log(LOG_ERROR, "Invalid priority: '%s'\n", args.arg3);
00144             goto return_cleanup;
00145          }
00146       } else if (args.argc == 3) {
00147          /* Exten not specified */
00148          exten = default_exten;
00149       }
00150 
00151       ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
00152             chantech, chandata, args.arg1, exten, priority);
00153 
00154       ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata,
00155             timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
00156             NULL, NULL, NULL, NULL);
00157    } else if (!strcasecmp(args.type, "app")) {
00158       ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
00159             chantech, chandata, args.arg1, S_OR(args.arg2, ""));
00160 
00161       ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata,
00162             timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
00163             NULL, NULL, NULL, NULL);
00164    } else {
00165       ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
00166             args.type);
00167       goto return_cleanup;
00168    }
00169 
00170    res = 0;
00171 
00172 return_cleanup:
00173    if (res) {
00174       pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "FAILED");
00175    } else {
00176       switch (outgoing_status) {
00177       case 0:
00178       case AST_CONTROL_ANSWER:
00179          pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "SUCCESS");
00180          break;
00181       case AST_CONTROL_BUSY:
00182          pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "BUSY");
00183          break;
00184       case AST_CONTROL_CONGESTION:
00185          pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "CONGESTION");
00186          break;
00187       case AST_CONTROL_HANGUP:
00188          pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "HANGUP");
00189          break;
00190       case AST_CONTROL_RINGING:
00191          pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "RINGING");
00192          break;
00193       default:
00194          ast_log(LOG_WARNING, "Unknown originate status result of '%d'\n",
00195                outgoing_status);
00196          pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "UNKNOWN");
00197          break;
00198       }
00199    }
00200 
00201    ast_autoservice_stop(chan);
00202 
00203    return res;
00204 }
00205 
00206 static int unload_module(void)
00207 {
00208    return ast_unregister_application(app_originate);
00209 }
00210 
00211 static int load_module(void)
00212 {
00213    int res;
00214 
00215    res = ast_register_application_xml(app_originate, originate_exec);
00216 
00217    return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00218 }
00219 
00220 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Originate call");

Generated on 7 Sep 2017 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1