function paging_get_config($engine) { global $db; global $ext; global $chan_dahdi; global $version; switch ($engine) { case "asterisk": $ast_ge_16 = version_compare($version, "1.6", "ge"); // setup for intercom $fcc = new featurecode('paging', 'intercom-prefix'); $intercom_code = $fcc->getCodeActive(); unset($fcc); // Since these are going down channel local, set ALERT_INFO and SIPADDHEADER which will be set in dialparties.agi // no point in even setting the headers here they will get lost in channel local // /* Set these up once here and in intercom so that autoanswer macro does not have * to go through this for every single extension which causes a lot of extra overhead * with big page groups */ $has_answermacro = false; $alertinfo = 'Alert-Info: Ring Answer'; $callinfo = 'Call-Info: <uri>\\;answer-after=0'; $sipuri = 'intercom=true'; $doptions = 'A(beep)'; $dtime = '5'; $custom_vars = array(); $autoanswer_arr = paging_get_autoanswer_defaults(); foreach ($autoanswer_arr as $autosetting) { switch (trim($autosetting['var'])) { case 'ALERTINFO': $alertinfo = trim($autosetting['setting']); break; case 'CALLINFO': $callinfo = trim($autosetting['setting']); break; case 'SIPURI': $sipuri = trim($autosetting['setting']); break; case 'VXML_URL': $vxml_url = trim($autosetting['setting']); break; case 'DOPTIONS': $doptions = trim($autosetting['setting']); break; case 'DTIME': $dtime = trim($autosetting['setting']); break; default: $key = trim($autosetting['var']); $custom_vars[$key] = trim($autosetting['setting']); if (ltrim($custom_vars[$key], '_') == "ANSWERMACRO") { $has_answermacro = true; } break; } } $extpaging = 'ext-paging'; if (!empty($intercom_code)) { $code = '_' . $intercom_code . '.'; $context = 'ext-intercom'; $ext->add($context, $code, '', new ext_macro('user-callerid')); $ext->add($context, $code, '', new ext_setvar('dialnumber', '${EXTEN:' . strlen($intercom_code) . '}')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/block)}" = "blocked"]', 'end')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(DND/${dialnumber})}" = "YES"]', 'end')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom/${AMPUSER})}" = "allow" ]', 'allow')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom/${AMPUSER})}" = "deny" ]', 'nointercom')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom)}" = "disabled" ]', 'nointercom')); $ext->add($context, $code, 'allow', new ext_dbget('DEVICES', 'AMPUSER/${dialnumber}/device')); $ext->add($context, $code, '', new ext_gotoif('$["${DEVICES}" = "" ]', 'end')); $ext->add($context, $code, '', new ext_setvar('LOOPCNT', '${FIELDQTY(DEVICES,&)}')); /* Set these up so that macro-autoanswer doesn't have to */ $ext->add($context, $code, '', new ext_setvar('_SIPURI', '')); if (trim($alertinfo) != "") { $ext->add($context, $code, '', new ext_setvar('_ALERTINFO', $alertinfo)); } if (trim($callinfo) != "") { $ext->add($context, $code, '', new ext_setvar('_CALLINFO', $callinfo)); } if (trim($sipuri) != "") { $ext->add($context, $code, '', new ext_setvar('_SIPURI', $sipuri)); } if (trim($vxml_url) != "") { $ext->add($context, $code, '', new ext_setvar('_VXML_URL', $vxml_url)); } if (trim($doptions) != "") { $ext->add($context, $code, '', new ext_setvar('_DOPTIONS', $doptions)); } foreach ($custom_vars as $key => $value) { $ext->add($context, $code, '', new ext_setvar('_' . ltrim($key, '_'), $value)); } $ext->add($context, $code, '', new ext_setvar('_DTIME', $dtime)); $ext->add($context, $code, '', new ext_setvar('_ANSWERMACRO', '')); $ext->add($context, $code, '', new ext_gotoif('$[${LOOPCNT} > 1 ]', 'pagemode')); $ext->add($context, $code, '', new ext_macro('autoanswer', '${DEVICES}')); if ($ast_ge_16) { $ext->add($context, $code, 'check', new ext_chanisavail('${DIAL}', 's')); $ext->add($context, $code, '', new ext_gotoif('$["${AVAILORIGCHAN}" == ""]', 'end')); } else { $ext->add($context, $code, 'check', new ext_chanisavail('${DIAL}', 'sj')); } $ext->add($context, $code, '', new ext_dial('${DIAL}', '${DTIME},${DOPTIONS}')); $ext->add($context, $code, 'end', new ext_busy()); $ext->add($context, $code, '', new ext_macro('hangupcall')); if (!$ast_ge_16) { $ext->add($context, $code, '', new ext_busy(), 'check', 101); $ext->add($context, $code, '', new ext_macro('hangupcall')); } $ext->add($context, $code, 'pagemode', new ext_setvar('ITER', '1')); $ext->add($context, $code, '', new ext_setvar('DIALSTR', '')); $ext->add($context, $code, 'begin', new ext_setvar('DIALSTR', '${DIALSTR}&LOCAL/PAGE${CUT(DEVICES,&,${ITER})}@' . $extpaging)); $ext->add($context, $code, '', new ext_setvar('ITER', '$[${ITER} + 1]')); $ext->add($context, $code, '', new ext_gotoif('$[${ITER} <= ${LOOPCNT}]', 'begin')); $ext->add($context, $code, '', new ext_setvar('DIALSTR', '${DIALSTR:1}')); $ext->add($context, $code, '', new ext_setvar('_AMPUSER', '${AMPUSER}')); $ext->add($context, $code, '', new ext_page('${DIALSTR},d')); $ext->add($context, $code, '', new ext_busy()); $ext->add($context, $code, '', new ext_macro('hangupcall')); $ext->add($context, $code, 'nointercom', new ext_noop('Intercom disallowed by ${dialnumber}')); $ext->add($context, $code, '', new ext_playback('intercom&for&extension')); $ext->add($context, $code, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $code, '', new ext_playback('is&disabled')); $ext->add($context, $code, '', new ext_congestion()); $extintercomusers = 'ext-intercom-users'; $userlist = core_users_list(); if (is_array($userlist)) { foreach ($userlist as $item) { $ext_intercom_code = $intercom_code . $item[0]; $ext->add($extintercomusers, $ext_intercom_code, '', new ext_goto($context . ',${EXTEN},1')); } } $context = $extintercomusers; $ext->addInclude('from-internal-additional', $context); } $fcc = new featurecode('paging', 'intercom-on'); $oncode = $fcc->getCodeActive(); unset($fcc); if ($oncode) { $ext->add($context, $oncode, '', new ext_answer('')); $ext->add($context, $oncode, '', new ext_wait('1')); $ext->add($context, $oncode, '', new ext_macro('user-callerid')); $ext->add($context, $oncode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'enabled')); $ext->add($context, $oncode, '', new ext_playback('intercom&enabled')); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $target = '${EXTEN:' . strlen($oncode) . '}'; $oncode = "_" . $oncode . "."; $ext->add($context, $oncode, '', new ext_answer('')); $ext->add($context, $oncode, '', new ext_wait('1')); $ext->add($context, $oncode, '', new ext_macro('user-callerid')); $ext->add($context, $oncode, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/' . $target . ')}" = "allow" ]}', 'unset')); $ext->add($context, $oncode, '', new ext_gotoif('$[${DB_EXISTS(AMPUSER/${EXTEN:3}/device)} != 1]', 'invaliduser')); $ext->add($context, $oncode, '', new ext_dbput('AMPUSER/${AMPUSER}/intercom/' . $target, 'allow')); $ext->add($context, $oncode, '', new ext_playback('intercom&enabled&for&extension&number')); $ext->add($context, $oncode, '', new ext_saydigits($target)); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $ext->add($context, $oncode, 'unset', new ext_dbdeltree('AMPUSER/${AMPUSER}/intercom/' . $target)); $ext->add($context, $oncode, '', new ext_playback('intercom&enabled&cancelled&for&extension&number')); $ext->add($context, $oncode, '', new ext_saydigits($target)); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $ext->add($context, $oncode, 'invaliduser', new ext_playback('extension&number')); $ext->add($context, $oncode, '', new ext_saydigits($target)); $ext->add($context, $oncode, '', new ext_playback('is&invalid')); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); } $fcc = new featurecode('paging', 'intercom-off'); $offcode = $fcc->getCodeActive(); unset($fcc); if ($offcode) { $ext->add($context, $offcode, '', new ext_answer('')); $ext->add($context, $offcode, '', new ext_wait('1')); $ext->add($context, $offcode, '', new ext_macro('user-callerid')); $ext->add($context, $offcode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'disabled')); $ext->add($context, $offcode, '', new ext_playback('intercom&disabled')); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $target = '${EXTEN:' . strlen($offcode) . '}'; $offcode = "_" . $offcode . "."; $ext->add($context, $offcode, '', new ext_answer('')); $ext->add($context, $offcode, '', new ext_wait('1')); $ext->add($context, $offcode, '', new ext_macro('user-callerid')); $ext->add($context, $offcode, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/' . $target . ')}" = "deny" ]}', 'unset2')); $ext->add($context, $offcode, '', new ext_gotoif('$[${DB_EXISTS(AMPUSER/${EXTEN:3}/device)} != 1]', 'invaliduser2')); $ext->add($context, $offcode, '', new ext_dbput('AMPUSER/${AMPUSER}/intercom/' . $target, 'deny')); $ext->add($context, $offcode, '', new ext_playback('intercom&disabled&for&extension&number')); $ext->add($context, $offcode, '', new ext_saydigits($target)); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $ext->add($context, $offcode, 'unset2', new ext_dbdeltree('AMPUSER/${AMPUSER}/intercom/' . $target)); $ext->add($context, $offcode, '', new ext_playback('intercom&disabled&cancelled&for&extension&number')); $ext->add($context, $offcode, '', new ext_saydigits($target)); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $ext->add($context, $offcode, 'invaliduser2', new ext_playback('extension&number')); $ext->add($context, $offcode, '', new ext_saydigits($target)); $ext->add($context, $offcode, '', new ext_playback('is&invalid')); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); } /* Create macro-autoanswer that will try to intelligently set the required parameters to handle paging. Eventually it will use known device information. This macro does the following: Input: FreePBX Device number to be called requiring autoanswer Output: ${DIAL} Channel Variable with the dial string to be called Appropriate SIP headers added Other special requirements that may be custom for this device 1. Set ${DIAL} to the device's dial string 2. If there is a device specific macro defined in the DEVICE's object (DEVICE/<devicenum>/autoanswer/macro) then execute that macro and end 3. Try to identify endpoints by their useragents that may need known changes and make those changes. These are generated from the paging_autoanswer table so users can extend them, if any are present 5. Set the variables and end unless a useragent specific ANSWERMACRO is defined in which case call it and end. This macro is called for intercoming and paging to try and enable the target device to auto-answer. Devices with special needs can be handled with the device specific macro. For example, if you have a device that can not auto-answer except by specifically configuring a line key on the device that always answers, you could use a device specific macro to change the dialstring. If you had a set of such devices, you could standardize on the device numbers (e.g. nnnn for normal calls and 2nnnn for auto-answer calls). You could then create a general purpose macro to modify the dial string accordingly. Provisioning tools will be able to take advantage of setting and creating such an ability. If you have a set of devices that can be identified with a SIP useragent then you can use a general macro without setting info in each device. */ $autoanswer_arr = paging_get_autoanswer_useragents(); $macro = 'macro-autoanswer'; $ext->add($macro, "s", '', new ext_setvar('DIAL', '${DB(DEVICE/${ARG1}/dial)}')); // If we are in DAHDI compat mode, then we need to substitute DAHDI for ZAP if ($chan_dahdi) { $ext->add($macro, "s", '', new ext_execif('$["${DIAL:0:3}" = "ZAP"]', 'Set', 'DIAL=DAHDI${DIAL:3}')); } $ext->add($macro, "s", '', new ext_gotoif('$["${DB(DEVICE/${ARG1}/autoanswer/macro)}" != "" ]', 'macro')); // If there are no phone specific auto-answer vars, then we don't care what the phone is below // if (!empty($autoanswer_arr)) { $ext->add($macro, "s", '', new ext_setvar('phone', '${SIPPEER(${CUT(DIAL,/,2)}:useragent)}')); } // We used to set all the variables here (ALERTINFO, CALLINFO, etc. That has been moved to each // paging group and the intercom main macro, since it was redundant for every phone causing a lot // of overhead with large page groups. // // Defaults are setup, now make specific adjustments for detected phones // These come from the SQL table as well where installations can make customizations // foreach ($autoanswer_arr as $autosetting) { $useragent = trim($autosetting['useragent']); $autovar = trim($autosetting['var']); $data = trim($autosetting['setting']); switch (ltrim($autovar, '_')) { case 'ANSWERMACRO': $has_answermacro = true; // fall through - no break on purpose // fall through - no break on purpose case 'ALERTINFO': case 'CALLINFO': case 'SIPURI': case 'VXML_URL': case 'DOPTIONS': case 'DTIME': default: if (trim($data) != "") { $ext->add($macro, "s", '', new ext_execif('$["${phone:0:' . strlen($useragent) . '}" = "' . $useragent . '"]', 'Set', $autovar . '=' . $data)); } break; } } // Now any adjustments have been made, set the headers and done // if ($has_answermacro) { $ext->add($macro, "s", '', new ext_gotoif('$["${ANSWERMACRO}" != ""]', 'macro2')); } $ext->add($macro, "s", '', new ext_execif('$["${ALERTINFO}" != ""]', 'SipAddHeader', '${ALERTINFO}')); $ext->add($macro, "s", '', new ext_execif('$["${CALLINFO}" != ""]', 'SipAddHeader', '${CALLINFO}')); $ext->add($macro, "s", '', new ext_execif('$["${SIPURI}" != ""]', 'Set', '__SIP_URI_OPTIONS=${SIPURI}')); $ext->add($macro, "s", 'macro', new ext_macro('${DB(DEVICE/${ARG1}/autoanswer/macro)}', '${ARG1}'), 'n', 2); if ($has_answermacro) { $ext->add($macro, "s", 'macro2', new ext_macro('${ANSWERMACRO}', '${ARG1}'), 'n', 2); } // Create the paging context that is used in the paging application for each phone to auto-answer // $ext->addInclude('from-internal-additional', $extpaging); // Normal page version $ext->add($extpaging, "_PAGE.", '', new ext_gotoif('$[ ${AMPUSER} = ${EXTEN:4} ]', 'skipself')); if ($ast_ge_16) { $ext->add($extpaging, "_PAGE.", 'AVAIL', new ext_chanisavail('${DB(DEVICE/${EXTEN:4}/dial)}', 's')); $ext->add($extpaging, "_PAGE.", '', new ext_gotoif('$["${AVAILORIGCHAN}" == ""]', 'skipself')); } else { $ext->add($extpaging, "_PAGE.", 'AVAIL', new ext_chanisavail('${DB(DEVICE/${EXTEN:4}/dial)}', 'js')); } $ext->add($extpaging, "_PAGE.", '', new ext_gotoif('$["${DB(DND/${DB(DEVICE/${EXTEN:4}/user)})}" = "YES"]', 'skipself')); $ext->add($extpaging, "_PAGE.", 'SKIPCHECK', new ext_macro('autoanswer', '${EXTEN:4}')); $ext->add($extpaging, "_PAGE.", '', new ext_dial('${DIAL}', '${DTIME},${DOPTIONS}')); $ext->add($extpaging, "_PAGE.", 'skipself', new ext_hangup()); if (!$ast_ge_16) { $ext->add($extpaging, "_PAGE.", '', new ext_hangup(''), 'AVAIL', 101); } // Force page version $ext->add($extpaging, "_FPAGE.", '', new ext_gotoif('$[ ${AMPUSER} = ${EXTEN:5} ]', 'skipself')); $ext->add($extpaging, "_FPAGE.", 'SKIPCHECK', new ext_macro('autoanswer', '${EXTEN:5}')); $ext->add($extpaging, "_FPAGE.", '', new ext_dial('${DIAL}', '${DTIME},${DOPTIONS}')); $ext->add($extpaging, "_FPAGE.", 'skipself', new ext_hangup()); // // Now get a list of all the paging groups... $sql = "SELECT page_group, force_page, duplex FROM paging_config"; $paging_groups = $db->getAll($sql, DB_FETCHMODE_ASSOC); foreach ($paging_groups as $thisgroup) { $grp = trim($thisgroup['page_group']); $pagemode = $thisgroup['force_page'] ? 'FPAGE' : 'PAGE'; $sql = "SELECT ext FROM paging_groups WHERE page_number='{$grp}'"; $all_exts = $db->getAll($sql); $dialstr = ''; foreach ($all_exts as $local_dial) { if (strtoupper(substr($local_dial[0], -1)) == "X") { $local_dial[0] = rtrim($local_dial[0], "xX"); } $dialstr .= "LOCAL/{$pagemode}" . trim($local_dial[0]) . "@" . $extpaging . "&"; } // It will always end with an &, so lets take that off. $dialstr = rtrim($dialstr, "&"); if ($thisgroup['duplex']) { $dialstr .= ",d"; } $ext->add($extpaging, $grp, '', new ext_answer('')); $ext->add($extpaging, $grp, '', new ext_macro('user-callerid')); // make AMPUSER inherited here, so we can skip the proper 'self' if using cidnum masquerading $ext->add($extpaging, $grp, '', new ext_setvar('_AMPUSER', '${AMPUSER}')); $ext->add($extpaging, $grp, '', new ext_setvar('_SIPURI', '')); if (trim($alertinfo) != "") { $ext->add($extpaging, $grp, '', new ext_setvar('_ALERTINFO', $alertinfo)); } if (trim($callinfo) != "") { $ext->add($extpaging, $grp, '', new ext_setvar('_CALLINFO', $callinfo)); } if (trim($sipuri) != "") { $ext->add($extpaging, $grp, '', new ext_setvar('_SIPURI', $sipuri)); } if (trim($vxml_url) != "") { $ext->add($extpaging, $grp, '', new ext_setvar('_VXML_URL', $vxml_url)); } if (trim($doptions) != "") { $ext->add($extpaging, $grp, '', new ext_setvar('_DOPTIONS', $doptions)); } $ext->add($extpaging, $grp, '', new ext_setvar('_DTIME', $dtime)); $ext->add($extpaging, $grp, '', new ext_setvar('_ANSWERMACRO', '')); foreach ($custom_vars as $key => $value) { $ext->add($extpaging, $grp, '', new ext_setvar('_' . ltrim($key, '_'), $value)); } $ext->add($extpaging, $grp, '', new ext_setvar('__FORWARD_CONTEXT', 'block-cf')); $ext->add($extpaging, $grp, '', new ext_page($dialstr)); } break; } }
public function doConfigPageInit($page) { $conf = \FreePBX::Config(); $ramp_conf = $conf->get_conf_settings(); foreach ($ramp_conf as $key => $value) { $amp_conf[$key] = $value['value']; } $request = $_REQUEST; $action = isset($request['action']) ? $request['action'] : null; $extdisplay = isset($request['extdisplay']) ? $request['extdisplay'] : null; if ($page == "extensions" || $page == "users") { // Catch the POST. if (isset($request['extdisplay']) && isset($request['intercom_override'])) { if (preg_match('/override=(.+)/', $request['intercom_override'], $match)) { $this->setOverride($request['extdisplay'], $match[1]); } } } if ($page == "paging") { $get_vars = array('action' => '', 'announce' => '', 'conflict_url' => '', 'default_group' => 0, 'description' => '', 'display' => 'paging', 'duplex' => 0, 'extdisplay' => '', 'force_page' => 0, 'pagegrp' => '', 'pagelist' => '', 'pagenbr' => '', 'Submit' => '', 'announcement' => '', 'type' => 'tool'); foreach ($get_vars as $k => $v) { $vars[$k] = isset($request[$k]) ? $request[$k] : $v; } $vars['pagenbr'] = trim($vars['pagenbr']); if ($vars['Submit'] == _('Delete')) { $vars['action'] = 'delete'; $request['action'] = 'delete'; } $vars['announce'] = $vars['announcement']; //action actions switch ($vars['action']) { case 'delete': paging_del($vars['extdisplay']); break; case 'submit': //TODO: issue, we are deleting and adding at the same time so remeber later to check // if we are deleting a destination $usage_arr = array(); if ($vars['pagegrp'] != $vars['pagenbr']) { $usage_arr = framework_check_extension_usage($vars['pagenbr']); } if ($usage_arr) { $vars['conflict_url'] = framework_display_extension_usage_alert($usage_arr); break; } else { //limit saved devices to PAGINGMAXPARTICIPANTS if (isset($amp_conf['PAGINGMAXPARTICIPANTS']) && $amp_conf['PAGINGMAXPARTICIPANTS']) { if (!empty($vars['pagelist'])) { $vars['pagelist'] = array_slice($vars['pagelist'], 0, $amp_conf['PAGINGMAXPARTICIPANTS']); } } paging_modify($vars['pagegrp'], $vars['pagenbr'], $vars['pagelist'], $vars['force_page'], $vars['duplex'], $vars['description'], $vars['default_group'], $vars['announcement']); $request['action'] = $vars['action'] = 'modify'; if ($vars['extdisplay'] == '' || $vars['pagegrp'] != $vars['pagenbr']) { $request['extdisplay'] = $vars['extdisplay'] = $vars['pagenbr']; } $_REQUEST['extdisplay'] = $vars['extdisplay']; } break; case 'save_settings': $def = paging_get_autoanswer_defaults(true); $doptions = 'b(autoanswer^s^1(${ALERTINFO},${CALLINFO}))'; if (ctype_digit($vars['announce'])) { $r = recordings_get($vars['announce']); if ($r) { $vars['announce'] = $r['filename']; } else { $vars['announce'] = 'beep'; } $a = 'A(' . $vars['announce'] . ')' . $doptions; } elseif ($vars['announce'] == 'none') { $a = "A(){$doptions}"; } elseif ($vars['announce'] == 'beep') { $a = "A(beep){$doptions}"; } $this->setDropSilence($state, !empty($vars['drop_silence'])); paging_set_autoanswer_defaults(array('DOPTIONS' => $a)); needreload(); break; case 'getJSON': header('Content-Type: application/json'); switch ($request['jdata']) { case 'grid': $pagelist = paging_list(); $rdata = array(); foreach ($pagelist as $pg) { $rdata[] = array('description' => $pg['description'], 'page_group' => $pg['page_group'], 'is_default' => $pg['is_default'], 'link' => array($pg['description'], $pg['page_group'])); } echo json_encode($rdata); exit; break; default: echo json_encode(array('error' => _("Unknown Request"))); exit; break; } break; default: break; } } }
function paging_get_config($engine) { global $db, $ext, $chan_dahdi, $version, $amp_conf, $conferences_conf; switch ($engine) { case "asterisk": // setup for intercom $fcc = new featurecode('paging', 'intercom-prefix'); $intercom_code = $fcc->getCodeActive(); unset($fcc); // Since these are going down channel local, set ALERT_INFO and SIPADDHEADER which will be set in dialparties.agi // no point in even setting the headers here they will get lost in channel local // /* Set these up once here and in intercom so that autoanswer macro does not have * to go through this for every single extension which causes a lot of extra overhead * with big page groups */ $has_answermacro = false; $alertinfo = 'Ring Answer'; $callinfo = '<uri>\\;answer-after=0'; $sipuri = 'intercom=true'; $doptions = 'A(beep)b(autoanswer^s^1(${ALERTINFO},${CALLINFO}))'; $vxml_url = ''; $dtime = '5'; $custom_vars = array(); $autoanswer_arr = paging_get_autoanswer_defaults(); foreach ($autoanswer_arr as $autosetting) { switch (trim($autosetting['var'])) { case 'ALERTINFO': $alertinfo = trim($autosetting['setting']); break; case 'CALLINFO': $callinfo = trim($autosetting['setting']); break; case 'SIPURI': $sipuri = trim($autosetting['setting']); break; case 'VXML_URL': $vxml_url = trim($autosetting['setting']); break; case 'DOPTIONS': $doptions = trim($autosetting['setting']); break; case 'DTIME': $dtime = trim($autosetting['setting']); break; default: $key = trim($autosetting['var']); $custom_vars[$key] = trim($autosetting['setting']); if (ltrim($custom_vars[$key], '_') == "ANSWERMACRO") { $has_answermacro = true; } break; } } $apppaging = 'app-paging'; if (!empty($intercom_code)) { $code = '_' . $intercom_code . '.'; $context = 'ext-intercom'; // Add for languages $ext->add($context, 'lang-playback', '', new ext_gosubif('$[${DIALPLAN_EXISTS(' . $context . ',${CHANNEL(language)})}]', $context . ',${CHANNEL(language)},${ARG1}', $context . ',en,${ARG1}')); $ext->add($context, 'lang-playback', '', new ext_return()); $ext->add($context, $code, '', new ext_macro('user-callerid')); $ext->add($context, $code, '', new ext_setvar('dialnumber', '${EXTEN:' . strlen($intercom_code) . '}')); $ext->add($context, $code, '', new ext_setvar('INTERCOM_CALL', 'TRUE')); $ext->add($context, $code, '', new ext_gosub('1', 's', 'sub-record-check', 'exten,${dialnumber}')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/block)}" = "blocked"]', 'end')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(DND/${dialnumber})}" = "YES"]', 'end')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom/${AMPUSER})}" = "allow" ]', 'allow')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom/${AMPUSER})}" = "deny" ]', 'nointercom')); $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom)}" = "disabled" ]', 'nointercom')); $ext->add($context, $code, 'allow', new ext_dbget('DEVICES', 'AMPUSER/${dialnumber}/device')); $ext->add($context, $code, '', new ext_gotoif('$["${DEVICES}" = "" ]', 'end')); $ext->add($context, $code, '', new ext_dbget('OVERRIDE', 'AMPUSER/${dialnumber}/intercom/override')); $ext->add($context, $code, '', new ext_setvar('LOOPCNT', '${FIELDQTY(DEVICES,&)}')); /* Set these up so that macro-autoanswer doesn't have to */ $ext->add($context, $code, '', new ext_setvar('_SIPURI', '')); if (trim($alertinfo) != "") { $ext->add($context, $code, '', new ext_setvar('_ALERTINFO', $alertinfo)); } if (trim($callinfo) != "") { $ext->add($context, $code, '', new ext_setvar('_CALLINFO', $callinfo)); } if (trim($sipuri) != "") { $ext->add($context, $code, '', new ext_setvar('_SIPURI', $sipuri)); } if (trim($vxml_url) != "") { $ext->add($context, $code, '', new ext_setvar('_VXML_URL', $vxml_url)); } foreach ($custom_vars as $key => $value) { $ext->add($context, $code, '', new ext_setvar('_' . ltrim($key, '_'), $value)); } $ext->add($context, $code, '', new ext_setvar('_DTIME', $dtime)); $ext->add($context, $code, '', new ext_setvar('_ANSWERMACRO', '')); $ext->add($context, $code, '', new ext_gotoif('$[${LOOPCNT} > 1 ]', 'pagemode')); $ext->add($context, $code, '', new ext_macro('autoanswer', '${DEVICES}')); $ext->add($context, $code, '', new ext_setvar('_DOPTIONS', $doptions)); $ext->add($context, $code, 'check', new ext_chanisavail('${DEVICE}', 's')); // If it's ringing for an inbound call, we should page. $ext->add($context, $code, '', new ext_execif('$["${AVAILSTATUS}" = "6"]', 'Set', 'AVAILORIGCHAN=${DEVICE}')); // Did we have a device we can page? If so, go to continue. If not, check for // paging override functions. $ext->add($context, $code, '', new ext_gotoif('$["${AVAILORIGCHAN}" != ""]', 'continue')); // Check the intercom override. $ext->add($context, $code, '', new ext_execif('$["${OVERRIDE}" = ""]', 'Set', 'OVERRIDE=reject')); $ext->add($context, $code, '', new ext_gotoif('$["${OVERRIDE}" = "reject"]', 'end')); // We don't know what the phones are going to do. Let's be generous. $ext->add($context, $code, '', new ext_set('DTIME', '30')); // If it's ring, treat it as a normal call. $ext->add($context, $code, '', new ext_execif('$["${OVERRIDE}" = "ring"]', 'Set', 'DOPTIONS=A(beep)')); // It's something else. Assume it's force, and just smash the device. $ext->add($context, $code, 'continue', new ext_noop('Continuing with page', 5)); $len = strlen($code) - 2; $dopt = 'I'; // Don't sent connectedline updates. $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${EXTEN:' . $len . '}/cidname)}" = ""]', 'godial')); $ext->add($context, $code, '', new ext_set('CONNECTEDLINE(name,i)', '${DB(AMPUSER/${EXTEN:' . $len . '}/cidname)}')); $ext->add($context, $code, '', new ext_set('CONNECTEDLINE(num)', '${EXTEN:' . $len . '}')); $ext->add($context, $code, 'godial', new ext_dial('${DIAL}', '${DTIME},' . $dopt . '${DOPTIONS}${INTERCOM_EXT_DOPTIONS}')); $ext->add($context, $code, 'end', new ext_execif('$[${INTERCOM_RETURN}]', 'Return')); $ext->add($context, $code, '', new ext_busy()); $ext->add($context, $code, '', new ext_macro('hangupcall')); $ext->add($context, $code, 'pagemode', new ext_setvar('ITER', '1')); $ext->add($context, $code, '', new ext_setvar('DIALSTR', '')); $ds = $amp_conf['ASTCONFAPP'] == 'app_confbridge' ? '${DIALSTR}-${CUT(DEVICES,&,${ITER})}' : '${DIALSTR}&LOCAL/PAGE${CUT(DEVICES,&,${ITER})}@' . $apppaging; $ext->add($context, $code, 'begin', new ext_chanisavail('${DB(DEVICE/${CUT(DEVICES,&,${ITER})}/dial)}', 's')); $ext->add($context, $code, '', new ext_gotoif('$["${AVAILORIGCHAN}" = ""]', 'skip')); $ext->add($context, $code, '', new ext_setvar('DIALSTR', $ds)); $ext->add($context, $code, 'skip', new ext_setvar('ITER', '$[${ITER} + 1]')); $ext->add($context, $code, '', new ext_gotoif('$[${ITER} <= ${LOOPCNT}]', 'begin')); $ext->add($context, $code, '', new ext_setvar('DIALSTR', '${DIALSTR:1}')); $ext->add($context, $code, '', new ext_gotoif('$["${DIALSTR}" = ""]', 'end2')); $ext->add($context, $code, '', new ext_setvar('_AMPUSER', '${AMPUSER}')); if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') { $ext->add($context, $code, '', new ext_gosub('1', 'page', false, '${DIALSTR}')); } else { $ext->add($context, $code, '', new ext_page('${DIALSTR},d')); } $ext->add($context, $code, 'end2', new ext_execif('$[${INTERCOM_RETURN}]', 'Return')); $ext->add($context, $code, '', new ext_busy()); $ext->add($context, $code, '', new ext_macro('hangupcall')); $ext->add($context, $code, 'nointercom', new ext_noop('Intercom disallowed by ${dialnumber}')); $ext->add($context, $code, '', new ext_execif('$[${INTERCOM_RETURN}]', 'Return')); $ext->add($context, $code, '', new ext_gosub('1', 'lang-playback', $context, 'hook_0')); $ext->add($context, $code, '', new ext_congestion()); if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') { $sub = 'page'; $ext->add($context, $sub, '', new ext_set('PAGE_CONF', '${EPOCH}${RAND(100,999)}')); $ext->add($context, $sub, '', new ext_set('PAGEMODE', 'PAGE')); $ext->add($context, $sub, '', new ext_set('PAGE_MEMBERS', '${ARG1}')); $ext->add($context, $sub, '', new ext_set('PAGE_CONF_OPTS', 'duplex')); $ext->add($context, $sub, '', new ext_agi('page.agi')); $ext->add($context, $sub, '', new ext_set('CONFBRIDGE(user,template)', 'page_user_duplex')); $ext->add($context, $sub, '', new ext_set('CONFBRIDGE(user,admin)', 'yes')); $ext->add($context, $sub, '', new ext_set('CONFBRIDGE(user,marked)', 'yes')); $ext->add($context, $sub, '', new ext_meetme('${PAGE_CONF}', ',', 'admin_menu')); $ext->add($context, $sub, '', new ext_hangup()); } $lang = 'en'; // English $ext->add($context, $lang, 'hook_0', new ext_playback('intercom&for&extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('is&disabled')); $ext->add($context, $lang, '', new ext_return()); $lang = 'ja'; // Japanese $ext->add($context, $lang, 'hook_0', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('jp-no&intercom&jp-wa&disabled-2')); $ext->add($context, $lang, '', new ext_return()); $extintercomusers = 'ext-intercom-users'; $sql = "SELECT LENGTH(id) as len FROM devices GROUP BY len"; $sth = FreePBX::Database()->prepare($sql); $sth->execute(); $rows = $sth->fetchAll(\PDO::FETCH_ASSOC); foreach ($rows as $row) { $ext->add($extintercomusers, '_' . $intercom_code . str_repeat('X', $row['len']), '', new ext_goto($context . ',${EXTEN},1')); } $context = $extintercomusers; // for language handling which is done on a per context basis $ext->add($context, 'lang-playback', '', new ext_gosubif('$[${DIALPLAN_EXISTS(' . $context . ',${CHANNEL(language)})}]', $context . ',${CHANNEL(language)},${ARG1}', $context . ',en,${ARG1}')); $ext->add($context, 'lang-playback', '', new ext_return()); $ext->addInclude('from-internal-additional', $context); } $fcc = new featurecode('paging', 'intercom-on'); $oncode = $fcc->getCodeActive(); unset($fcc); if ($oncode) { $ext->add($context, $oncode, '', new ext_macro('user-callerid')); $ext->add($context, $oncode, '', new ext_set('CONNECTEDLINE(name-charset,i)', 'utf8')); $ext->add($context, $oncode, '', new ext_set('CONNECTEDLINE(name,i)', _("Intercom: Enabled"))); $ext->add($context, $oncode, '', new ext_set('CONNECTEDLINE(num,i)', '${AMPUSER}')); $ext->add($context, $oncode, '', new ext_answer('')); $ext->add($context, $oncode, '', new ext_wait('1')); $ext->add($context, $oncode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'enabled')); $ext->add($context, $oncode, '', new ext_playback('intercom&enabled')); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $target = '${EXTEN:' . strlen($oncode) . '}'; $oncode = "_" . $oncode . "."; $ext->add($context, $oncode, '', new ext_macro('user-callerid')); $ext->add($context, $oncode, '', new ext_set('CONNECTEDLINE(name-charset,i)', 'utf8')); $ext->add($context, $oncode, '', new ext_set('CONNECTEDLINE(name,i)', sprintf(_("Intercom from %s: Enabled"), $target))); $ext->add($context, $oncode, '', new ext_set('CONNECTEDLINE(num,i)', '${AMPUSER}')); $ext->add($context, $oncode, '', new ext_setvar('dialnumber', '${EVAL(${EXTEN:' . strlen(substr($oncode, 1, -1)) . '})}')); // Asterisk variable for saydigits languages $ext->add($context, $oncode, '', new ext_answer('')); $ext->add($context, $oncode, '', new ext_wait('1')); $ext->add($context, $oncode, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/' . $target . ')}" = "allow" ]}', 'unset')); $ext->add($context, $oncode, '', new ext_gotoif('$[${DB_EXISTS(AMPUSER/' . $target . '/device)} != 1]', 'invaliduser')); $ext->add($context, $oncode, '', new ext_dbput('AMPUSER/${AMPUSER}/intercom/' . $target, 'allow')); $ext->add($context, $oncode, '', new ext_gosub('1', 'lang-playback', $context, 'hook_1')); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $ext->add($context, $oncode, 'unset', new ext_dbdeltree('AMPUSER/${AMPUSER}/intercom/' . $target)); $ext->add($context, $oncode, '', new ext_gosub('1', 'lang-playback', $context, 'hook_2')); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $ext->add($context, $oncode, 'invaliduser', new ext_gosub('1', 'lang-playback', $context, 'hook_3')); $ext->add($context, $oncode, '', new ext_macro('hangupcall')); $lang = 'en'; // English $ext->add($context, $lang, 'hook_1', new ext_playback('intercom&from&extension&number')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('enabled')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_2', new ext_playback('intercom&enabled&cancelled&for&extension&number')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_3', new ext_playback('extension&number')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('invalid')); $ext->add($context, $lang, '', new ext_return()); $lang = 'ja'; // Japanese $ext->add($context, $lang, 'hook_1', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('jp-kara&jp-no&intercom&jp-wo&allow')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_2', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('jp-kara&jp-no&intercom&setting&jp-wo&cancelled')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_3', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('invalid')); $ext->add($context, $lang, '', new ext_return()); } $fcc = new featurecode('paging', 'intercom-off'); $offcode = $fcc->getCodeActive(); unset($fcc); if ($offcode) { $ext->add($context, $offcode, '', new ext_macro('user-callerid')); $ext->add($context, $offcode, '', new ext_set('CONNECTEDLINE(name-charset,i)', 'utf8')); $ext->add($context, $offcode, '', new ext_set('CONNECTEDLINE(name,i)', _("Intercom: Disabled"))); $ext->add($context, $offcode, '', new ext_set('CONNECTEDLINE(num,i)', '${AMPUSER}')); $ext->add($context, $offcode, '', new ext_answer('')); $ext->add($context, $offcode, '', new ext_wait('1')); $ext->add($context, $offcode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'disabled')); $ext->add($context, $offcode, '', new ext_playback('intercom&disabled')); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $target = '${EXTEN:' . strlen($offcode) . '}'; $offcode = "_" . $offcode . "."; $ext->add($context, $offcode, '', new ext_macro('user-callerid')); $ext->add($context, $offcode, '', new ext_set('CONNECTEDLINE(name-charset,i)', 'utf8')); $ext->add($context, $offcode, '', new ext_set('CONNECTEDLINE(name,i)', sprintf(_("Intercom from %s: Disabled"), $target))); $ext->add($context, $offcode, '', new ext_set('CONNECTEDLINE(num,i)', '${AMPUSER}')); $ext->add($context, $offcode, '', new ext_setvar('dialnumber', '${EVAL(${EXTEN:' . strlen(substr($offcode, 1, -1)) . '})}')); // Asterisk variable for saydigits languages $ext->add($context, $offcode, '', new ext_answer('')); $ext->add($context, $offcode, '', new ext_wait('1')); $ext->add($context, $offcode, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/' . $target . ')}" = "deny" ]}', 'unset2')); $ext->add($context, $offcode, '', new ext_gotoif('$[${DB_EXISTS(AMPUSER/' . $target . '/device)} != 1]', 'invaliduser2')); $ext->add($context, $offcode, '', new ext_dbput('AMPUSER/${AMPUSER}/intercom/' . $target, 'deny')); $ext->add($context, $offcode, '', new ext_gosub('1', 'lang-playback', $context, 'hook_4')); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $ext->add($context, $offcode, 'unset2', new ext_dbdeltree('AMPUSER/${AMPUSER}/intercom/' . $target)); $ext->add($context, $offcode, '', new ext_gosub('1', 'lang-playback', $context, 'hook_5')); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $ext->add($context, $offcode, 'invaliduser2', new ext_gosub('1', 'lang-playback', $context, 'hook_6')); $ext->add($context, $offcode, '', new ext_macro('hangupcall')); $lang = 'en'; $ext->add($context, $lang, 'hook_4', new ext_playback('intercom&from&extension&number')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('disabled')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_5', new ext_playback('intercom&disabled&cancelled&for&extension&number')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_6', new ext_playback('extension&number')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('invalid')); $ext->add($context, $lang, '', new ext_return()); $lang = 'ja'; $ext->add($context, $lang, 'hook_4', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('jp-kara&jp-no&intercom&jp-wo&deny')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_5', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('jp-kara&jp-no&intercom&setting&jp-wo&cancelled')); $ext->add($context, $lang, '', new ext_return()); $ext->add($context, $lang, 'hook_6', new ext_playback('extension')); $ext->add($context, $lang, '', new ext_saydigits('${dialnumber}')); $ext->add($context, $lang, '', new ext_playback('invalid')); $ext->add($context, $lang, '', new ext_return()); } /* Create macro-autoanswer that will try to intelligently set the required parameters to handle paging. Eventually it will use known device information. This macro does the following: Input: FreePBX Device number to be called requiring autoanswer Output: ${DIAL} Channel Variable with the dial string to be called Appropriate SIP headers added Other special requirements that may be custom for this device 1. Set ${DIAL} to the device's dial string 2. If there is a device specific macro defined in the DEVICE's object (DEVICE/<devicenum>/autoanswer/macro) then execute that macro and end 3. Try to identify endpoints by their useragents that may need known changes and make those changes. These are generated from the paging_autoanswer table so users can extend them, if any are present 5. Set the variables and end unless a useragent specific ANSWERMACRO is defined in which case call it and end. This macro is called for intercoming and paging to try and enable the target device to auto-answer. Devices with special needs can be handled with the device specific macro. For example, if you have a device that can not auto-answer except by specifically configuring a line key on the device that always answers, you could use a device specific macro to change the dialstring. If you had a set of such devices, you could standardize on the device numbers (e.g. nnnn for normal calls and 2nnnn for auto-answer calls). You could then create a general purpose macro to modify the dial string accordingly. Provisioning tools will be able to take advantage of setting and creating such an ability. If you have a set of devices that can be identified with a SIP useragent then you can use a general macro without setting info in each device. */ $autoanswer_arr = paging_get_autoanswer_useragents(); $macro = 'macro-autoanswer'; // Do we already know what the correct string is? This may have been handed to us // by page.agi. $ext->add($macro, "s", '', new ext_gotoif('$["${KNOWNDIAL}" != ""]', 'knowndial')); // Do we have a PJSIP Endpoint? $ext->add($macro, "s", '', new ext_setvar('DEVICE', '${DB(DEVICE/${ARG1}/dial)}')); $ext->add($macro, "s", '', new ext_gotoif('$["${DEVICE:0:5}" == "PJSIP" ]', 'dopjsip')); // We're not pjsip, so our dial is going to be our device $ext->add($macro, "s", '', new ext_setvar('KNOWNDIAL', '${DEVICE}')); $ext->add($macro, "s", '', new ext_goto('knowndial')); // Handle PJSIP stuff. $ext->add($macro, "s", 'dopjsip', new ext_setvar('KNOWNDIAL', '${PJSIP_DIAL_CONTACTS(${ARG1})}')); // If there's an ampersand, there's more than one device registered to this endpoint, and we // need to page, rather than intercom. $ext->add($macro, "s", '', new ext_gotoif('$[${REGEX("&" ${KNOWNDIAL})} == 0]', 'knowndial')); // Bugger. However, we can hard-code some settings here that'll make our life a bit easier. $ext->add($macro, "s", '', new ext_gosub('1', 'ssetup', 'app-paging')); $ext->add($macro, "s", '', new ext_setvar('PAGEMODE', 'PAGE')); $ext->add($macro, "s", '', new ext_setvar('PAGE_CONF_OPTS', 'duplex')); $ext->add($macro, "s", '', new ext_setvar('STREAM', 'NONE')); $ext->add($macro, "s", '', new ext_setvar('PAGE_MEMBERS', '${ARG1}')); // Start the AGI to get the clients into the conf $ext->add($macro, "s", '', new ext_agi('page.agi')); // Now I need to join the conf as admin. $ext->add($macro, "s", '', new ext_set('CONFBRIDGE(user,template)', 'page_user_duplex')); $ext->add($macro, "s", '', new ext_set('CONFBRIDGE(user,admin)', 'yes')); $ext->add($macro, "s", '', new ext_set('CONFBRIDGE(user,marked)', 'yes')); $ext->add($macro, "s", '', new ext_meetme('${PAGE_CONF}', ',', 'admin_menu')); // ext_confbridge, actually. $ext->add($macro, "s", '', new ext_hangup()); // Don't even try to continue after this. // Right. Bypassing all that, it's a single device, and, we know what our dial string is. $ext->add($macro, "s", 'knowndial', new ext_setvar('DIAL', '${KNOWNDIAL}')); // If we are in DAHDI compat mode, then we need to substitute DAHDI for ZAP if ($chan_dahdi) { $ext->add($macro, "s", '', new ext_execif('$["${DIAL:0:3}" = "ZAP"]', 'Set', 'DIAL=DAHDI${DIAL:3}')); } $ext->add($macro, "s", '', new ext_gotoif('$["${DB(DEVICE/${ARG1}/autoanswer/macro)}" != "" ]', 'macro')); // If there are no phone specific auto-answer vars, then we don't care what the phone is below // if (!empty($autoanswer_arr)) { global $version; $ext->add($macro, "s", '', new ext_gotoif('$["${DIAL:0:5}" = "PJSIP"]', 'pjsipua')); //http://issues.freepbx.org/browse/FREEPBX-7715 if (version_compare($version, "12", "<")) { $ext->add($macro, "s", '', new ext_setvar('USERAGENT', '${SIPPEER(${CUT(DIAL,/,2)}:useragent)}')); } else { $ext->add($macro, "s", '', new ext_setvar('USERAGENT', '${SIPPEER(${CUT(DIAL,/,2)},useragent)}')); } $ext->add($macro, "s", '', new ext_goto('uafin')); $ext->add($macro, "s", 'pjsipua', new ext_setvar('AOR', '${CUT(DIAL,/,2)}')); $ext->add($macro, "s", '', new ext_setvar('CONTACT', '${PJSIP_AOR(${AOR},contact)}')); $ext->add($macro, "s", '', new ext_setvar('USERAGENT', '${PJSIP_CONTACT(${CONTACT},user_agent)}')); $ext->add($macro, "s", 'uafin', new ext_execif('$["${KNOWNAGENT}" != ""]', 'Set', 'USERAGENT=${KNOWNAGENT}')); } // We used to set all the variables here (ALERTINFO, CALLINFO, etc. That has been moved to each // paging group and the intercom main macro, since it was redundant for every phone causing a lot // of overhead with large page groups. // // Defaults are setup, now make specific adjustments for detected phones // These come from the SQL table as well where installations can make customizations // foreach ($autoanswer_arr as $autosetting) { $useragent = trim($autosetting['useragent']); $autovar = trim($autosetting['var']); $data = trim($autosetting['setting']); switch (ltrim($autovar, '_')) { case 'ANSWERMACRO': $has_answermacro = true; // fall through - no break on purpose // fall through - no break on purpose case 'ALERTINFO': case 'CALLINFO': case 'SIPURI': case 'VXML_URL': case 'DOPTIONS': case 'DTIME': default: if (trim($data) != "") { $ext->add($macro, "s", '', new ext_execif('$["${USERAGENT:0:' . strlen($useragent) . '}" = "' . $useragent . '"]', 'Set', $autovar . '=' . $data)); } break; } } // Now any adjustments have been made, set the headers and done // if ($has_answermacro) { $ext->add($macro, "s", '', new ext_gotoif('$["${ANSWERMACRO}" != ""]', 'macro2')); } $ext->add($macro, "s", '', new ext_execif('$["${SIPURI}" != ""]', 'Set', '__SIP_URI_OPTIONS=${SIPURI}')); $ext->add($macro, "s", 'macro', new ext_macro('${DB(DEVICE/${ARG1}/autoanswer/macro)}', '${ARG1}'), 'n', 2); if ($has_answermacro) { $ext->add($macro, "s", 'macro2', new ext_macro('${ANSWERMACRO}', '${ARG1}'), 'n', 2); } //auto answer stuff //set autoanswer variables if (!empty($custom_vars)) { foreach ($custom_vars as $key => $value) { $ext->add($apppaging, '_AUTOASWER.', '', new ext_setvar('_' . ltrim($key, '_'), $value)); } $ext->add($apppaging, '_AUTOASWER.', '', new ext_macro('autoanswer', '${EXTEN:9}')); $ext->add($apppaging, '_AUTOASWER.', '', new ext_return()); } // Macro to apply SIP Headers to channel. // function ext_gosubif($condition, $true_priority, $false_priority = false, $true_args = '', $false_args = '') { // $ext->add("autoanswer", "s", '', new ext_gosubif('$["${ARG1}" != ""]', 'func-set-sipheader,s,1', false, 'Alert-Info,${ARG1}')); $ext->add("autoanswer", "s", '', new ext_gosubif('$["${ARG2}" != ""]', 'func-set-sipheader,s,1', false, 'Call-Info,${ARG2}')); $ext->add("autoanswer", "s", '', new ext_gosub('func-apply-sipheaders,s,1')); $ext->add("autoanswer", "s", '', new ext_return()); // Setup Variables before AGI script // $ext->add($apppaging, 'ssetup', '', new ext_set('_SIPURI', '')); if (isset($alertinfo) && trim($alertinfo) != "") { $ext->add($apppaging, 'ssetup', '', new ext_set('_ALERTINFO', $alertinfo)); } if (isset($callinfo) && trim($callinfo) != "") { $ext->add($apppaging, 'ssetup', '', new ext_set('_CALLINFO', $callinfo)); } if (isset($sipuri) && trim($sipuri) != "") { $ext->add($apppaging, 'ssetup', '', new ext_set('_SIPURI', $sipuri)); } if (isset($vxml_url) && trim($vxml_url) != "") { $ext->add($apppaging, 'ssetup', '', new ext_set('_VXML_URL', $vxml_url)); } $ext->add($apppaging, 'ssetup', '', new ext_set('_DTIME', $dtime)); $ext->add($apppaging, 'ssetup', '', new ext_set('_ANSWERMACRO', '')); $page_opts = $amp_conf['ASTCONFAPP'] == 'app_confbridge' ? '1qs' : '1dqsx'; $ext->add($apppaging, 'ssetup', '', new ext_set('PAGE_CONF', '${EPOCH}${RAND(100,999)}')); $ext->add($apppaging, 'ssetup', '', new ext_return()); // Normal page version (now used for Force also) // If we had any custom_vars then call the AUTOASWER subroutine first, otherwise go // straight to macro-autoanswer if (!empty($custom_vars)) { $ext->add($apppaging, "_PAGE.", 'SKIPCHECK', new ext_gosub('AUTOASWER${EXTEN:4},1')); } else { $ext->add($apppaging, "_PAGE.", 'SKIPCHECK', new ext_macro('autoanswer', '${EXTEN:4}')); } $ext->add($apppaging, "_PAGE.", '', new ext_noop('${EXTRINGTIME}')); $ext->add($apppaging, "_PAGE.", '', new ext_gotoif('$["${EXTRINGTIME}" != "true"]', 'doptions')); $ext->add($apppaging, "_PAGE.", '', new ext_set('_DTIME', '${RINGTIMER_DEFAULT}')); $ext->add($apppaging, "_PAGE.", '', new ext_execif('$["${DB(AMPUSER/${EXTEN:4}/ringtimer)}" != "" & ${DB(AMPUSER/${EXTEN:4}/ringtimer)} > 0]', 'Set', '_DTIME=${DB(AMPUSER/${EXTEN:4}/ringtimer)}')); //strip the global Announcement out of doptions (We use our announcement variable lower --V) $doptions2 = preg_replace("/A\\([^\\)]*\\)/", "", $doptions); $ext->add($apppaging, "_PAGE.", 'doptions', new ext_execif('$["${DOPTIONS}" = ""]', 'Set', '_DOPTIONS=' . $doptions2)); $ext->add($apppaging, "_PAGE.", '', new ext_dial('${DIAL}', '${DTIME},A(${ANNOUNCEMENT})${DOPTIONS}')); $ext->add($apppaging, "_PAGE.", 'skipself', new ext_hangup()); // Try ChanSpy Version $ext->add($apppaging, "_SPAGE.", 'chanspy', new ext_chanspy('${SP_DEVICE}-', 'qW')); $ext->add($apppaging, "_SPAGE.", '', new ext_hangup()); // If Asterisk 10 and app_confbridge: // // Common to admin: // d: dynamically addd conf // o: talker optimization (don't mix non-talkers) // q: quiet mode no enter/leave sounds // x: close conf when last marked user exits // // Not in Admin: // 1: ??? // s: present menu //See http://issues.freepbx.org/browse/FREEPBX-8796 //before you even think about removing this to after checking for a page group! if ($amp_conf['ASTCONFAPP'] == 'app_confbridge' && isset($conferences_conf) && is_a($conferences_conf, "conferences_conf")) { $pu = 'page_user'; $pud = 'page_user_duplex'; foreach (array($pu, $pud) as $u) { $conferences_conf->addConfUser($u, 'quiet', 'yes'); $conferences_conf->addConfUser($u, 'announce_user_count', 'no'); $conferences_conf->addConfUser($u, 'wait_marked', 'yes'); $conferences_conf->addConfUser($u, 'end_marked', 'yes'); $dds = \FreePBX::Paging()->getDropSilence() ? 'yes' : 'no'; $conferences_conf->addConfUser($u, 'dsp_drop_silence', $dds); $conferences_conf->addConfUser($u, 'announce_join_leave', 'no'); $conferences_conf->addConfUser($u, 'admin', 'no'); $conferences_conf->addConfUser($u, 'marked', 'no'); } $conferences_conf->addConfUser($pu, 'startmuted', 'yes'); } //page playback $c = 'app-page-stream'; $ext->add($c, 's', '', new ext_wait(1)); $ext->add($c, 's', '', new ext_answer()); // TODO: PAGE_CONF_OPTS reset in agi script so just use proper context if 10+confbridge no mute // x: close conf when last marked user exits // q: quiet mode no enter/leave sounds // // TODO: Ideally what we want is to mark the stream and wait for that, if no stream then no wait for makred user. However // it seems like to end a conference you have to have the kick after last marked user since there doesn't have to be // an admin as far as I can tell. // // if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') { $ext->add($c, 's', '', new ext_set('CONFBRIDGE(user,template)', $pud)); $ext->add($c, 's', '', new ext_set('CONFBRIDGE(user,marked)', 'yes')); $ext->add($c, 's', '', new ext_meetme('${PAGE_CONF}', '', '')); } else { $ext->add($c, 's', '', new ext_meetme('${PAGE_CONF}', '${PAGE_CONF_OPTS}')); } $ext->add($c, 's', '', new ext_hangup()); $apppagegroups = 'app-pagegroups'; // Now get a list of all the paging groups... $sql = "SELECT page_group, force_page, duplex, announcement FROM paging_config"; $paging_groups = $db->getAll($sql, DB_FETCHMODE_ASSOC); if (!$paging_groups) { break; //no need to continue if we dont have any pagegroups } $extpaging = 'ext-paging'; if (!empty($paging_groups)) { $ext->addInclude('from-internal-noxfer-additional', $extpaging); } foreach ($paging_groups as $thisgroup) { $grp = trim($thisgroup['page_group']); switch ($thisgroup['force_page']) { case 1: $pagemode = 'FPAGE'; break; case 2: $pagemode = 'SPAGE'; break; case 0: default: $pagemode = 'PAGE'; break; } $sql = "SELECT ext FROM paging_groups WHERE page_number='{$grp}'"; $all_exts = $db->getCol($sql); // Create the paging context that is used in the paging application for each phone to auto-answer //add ext-paging with goto's to our app-paging context and a hint for the page $ext->add($extpaging, $grp, '', new ext_goto($apppagegroups . ',' . $grp . ',1')); $ext->addHint($extpaging, $grp, 'Custom:PAGE' . $grp); //app-page dialplan $ext->add($apppagegroups, $grp, '', new ext_macro('user-callerid')); $ext->add($apppagegroups, $grp, '', new ext_set('_PAGEGROUP', $grp)); //if page group it in use, goto to busy $ext->add($apppagegroups, $grp, 'busy-check', new ext_gotoif('$[${TRYLOCK(apppagegroups' . $grp . ')}]', '', 'busy')); //set blf to in use $ext->add($apppagegroups, $grp, 'devstate', new ext_setvar('DEVICE_STATE(Custom:PAGE' . $grp . ')', 'INUSE')); $ext->add($apppagegroups, $grp, '', new ext_gosub('1', 'ssetup', $apppaging)); $ext->add($apppagegroups, $grp, '', new ext_set('PAGEMODE', $pagemode)); $ext->add($apppagegroups, $grp, '', new ext_set('PAGE_MEMBERS', implode('-', $all_exts))); if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') { $ext->add($apppagegroups, $grp, '', new ext_set('PAGE_CONF_OPTS', $thisgroup['duplex'] ? 'duplex' : '')); } else { $ext->add($apppagegroups, $grp, '', new ext_set('PAGE_CONF_OPTS', $page_opts . (!$thisgroup['duplex'] ? 'm' : ''))); } //Default announcement is a beep $announcement = "beep"; //extract our "global default announcement" from the doptions and set it to announcement if (preg_match("/A\\(([^\\)]*)\\)/", $doptions, $matches)) { $announcement = isset($matches[1]) ? $matches[1] : ""; } //get our individual page group announcement if set if (!empty($thisgroup['announcement'])) { switch ($thisgroup['announcement']) { case "beep": $announcement = "beep"; break; case "none": $announcement = ""; break; case "default": //do nothing break; default: if (function_exists('recordings_get_file')) { $announcement = recordings_get_file($thisgroup['announcement']); } else { $announcement = ""; } break; } } $ext->add($apppagegroups, $grp, '', new ext_set('ANNOUNCEMENT', $announcement)); $ext->add($apppagegroups, $grp, 'agi', new ext_agi('page.agi')); //we cant use originate from the dialplan as the dialplan command is not asynchronous //we would like to though... //this code here as a sign of hope -MB /*foreach ($page_members as $member) { $ext->add($apppagegroups, $grp, 'page', new ext_originate($member,'app','meetme', '${PAGE_CONF}\,${PAGE_CONF_OPTS}')); }*/ // TODO this is the master so set appropriate // This is what everyone else has: 1doqsx // Common: // d: dynamically addd conf // o: talker optimization (don't mix non-talkers) // q: quiet mode no enter/leave sounds // x: close conf when last marked user exits // Added: // w: W() wait until marked user enters conf // A: Set marked mode // G: G() Play an intro announcemend in conference // Removed: // 1: ??? // s: present menu // // if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') { $ext->add($apppagegroups, $grp, '', new ext_set('CONFBRIDGE(user,template)', $pud)); $ext->add($apppagegroups, $grp, '', new ext_set('CONFBRIDGE(user,admin)', 'yes')); $ext->add($apppagegroups, $grp, '', new ext_set('CONFBRIDGE(user,marked)', 'yes')); // TODO: should I have no menu? $ext->add($apppagegroups, $grp, '', new ext_answer('')); $ext->add($apppagegroups, $grp, 'page', new ext_meetme('${PAGE_CONF}', ',', 'admin_menu')); } else { $ext->add($apppagegroups, $grp, '', new ext_answer('')); $ext->add($apppagegroups, $grp, 'page', new ext_meetme('${PAGE_CONF}', 'dqwxAG')); } $ext->add($apppagegroups, $grp, '', new ext_hangup()); $ext->add($apppagegroups, $grp, 'busy', new ext_set('PAGE${PAGEGROUP}BUSY', 'TRUE')); $ext->add($apppagegroups, $grp, 'play-busy', new ext_busy(3)); $ext->add($apppagegroups, $grp, 'busy-hang', new ext_goto('app-pagegroups,h,1')); } //h $ext->add($apppagegroups, 'h', '', new ext_execif('$[${ISNULL(${PAGE${PAGEGROUP}BUSY})}]', 'Set', 'DEVICE_STATE(Custom:PAGE${PAGEGROUP})=NOT_INUSE')); break; } }
<?php $rec_list['none'] = _('None'); $rec_list['beep'] = _('Default'); if (!function_exists('recordings_list')) { $announce = 'default'; } else { //build recordings list foreach (recordings_list() as $rec) { $rec_list[$rec['id']] = $rec['displayname']; } //get paging defaults $def = paging_get_autoanswer_defaults(true); $announce = 'beep'; if (isset($def['DOPTIONS'])) { preg_match('/A\\((.*?)\\)/', $def['DOPTIONS'], $m); //blank file? That would be 'none' if (isset($m[0]) && (!isset($m[1]) || !$m[1])) { $announce = 'none'; //otherwise, get the ID of the system recording } elseif (isset($m[0], $m[1])) { foreach (recordings_list() as $raw) { if ($raw['filename'] == $m[1]) { $announce = $raw['id']; break; } } } } } $aopts = '';