public static function set($autoattendant) { $xml = FreeSwitch::setSection('autoattendant', $autoattendant['auto_attendant_id']); media::generateConfig($autoattendant, $xml); if (!empty($autoattendant['extension_context_id'])) { $xml->setAttributeValue('', 'digit-len', $autoattendant['extension_digits']); } $xml->setAttributeValue('', 'timeout', $autoattendant['timeout'] * 1000); $xml->setAttributeValue('', 'inter-digit-timeout', $autoattendant['digit_timeout'] * 1000); if (!empty($autoattendant['registry']['max-failures'])) { $xml->setAttributeValue('', 'max-failures', $autoattendant['registry']['max-failures']); } else { $xml->setAttributeValue('', 'max-failures', '3'); } $xml->deleteChildren(); if (!empty($autoattendant['extension_context_id'])) { $xml->update(sprintf('/entry[@action="menu-exec-app"][@name="catch_all"][@digits="\\/^([0-9]{%s})$\\/"][@param="execute_extension $1 XML context_%s"]', $autoattendant['extension_digits'], $autoattendant['extension_context_id'])); } foreach ($autoattendant['keys'] as $key) { if (!isset($key['digits'])) { continue; } if (!($transferString = fs::getTransferToNumber($key['number_id']))) { continue; } $xml->update(sprintf('/entry[@action="menu-exec-app"][@digits="%s"][@param="transfer %s"]', $key['digits'], $transferString)); } }
public static function set($autoattendant) { $xml = FreeSwitch::setSection('autoattendant', $autoattendant['auto_attendant_id']); if (empty($autoattendant['registry']['mediafile_id']) or !class_exists('Media')) { $type = 'tty'; } else { $type = $autoattendant['registry']['type']; } switch ($type) { case 'audio': $xml->setAttributeValue('', 'greet-long', Media::getMediaFile($autoattendant['registry']['mediafile_id'])); $xml->setAttributeValue('', 'greet-short', Media::getMediaFile($autoattendant['registry']['mediafile_id'])); break; default: if (empty($autoattendant['registry']['tts_string'])) { $tts_string = 'Thank you for calling, your call is important to us.'; } else { $tts_string = $autoattendant['registry']['tts_string']; } $tts_string = 'say:' . preg_replace('/[^A-Za-z0-9.,!? ]/', '', $tts_string); $xml->setAttributeValue('', 'tts-engine', 'flite'); $xml->setAttributeValue('', 'tts-voice', 'kal'); $xml->setAttributeValue('', 'greet-long', $tts_string); $xml->setAttributeValue('', 'greet-short', $tts_string); } if (!empty($autoattendant['extension_context_id'])) { $xml->setAttributeValue('', 'digit-len', $autoattendant['extension_digits']); } $xml->setAttributeValue('', 'timeout', $autoattendant['timeout'] * 1000); $xml->setAttributeValue('', 'inter-digit-timeout', $autoattendant['digit_timeout'] * 1000); if (!empty($autoattendant['registry']['max-failures'])) { $xml->setAttributeValue('', 'max-failures', $autoattendant['registry']['max-failures']); } else { $xml->setAttributeValue('', 'max-failures', '3'); } $xml->deleteChildren(); if (!empty($autoattendant['extension_context_id'])) { $xml->update(sprintf('/entry[@action="menu-exec-app"][@name="catch_all"][@digits="\\/^([0-9]{%s})$\\/"][@param="execute_extension $1 XML context_%s"]', $autoattendant['extension_digits'], $autoattendant['extension_context_id'])); } foreach ($autoattendant['keys'] as $key) { if (!isset($key['digits'])) { continue; } if (!($transferString = fs::getTransferToNumber($key['number_id']))) { continue; } $xml->update(sprintf('/entry[@action="menu-exec-app"][@digits="%s"][@param="transfer %s"]', $key['digits'], $transferString)); } }
public static function dialplan($number) { $xml = Telephony::getDriver()->xml; $destination = $number['Destination']; if (!empty($destination['time'])) { $parts = explode(';', $destination['time']); if (count($parts) != 2) { kohana::log('error', 'Time was not comprised of two parts'); return FALSE; } if ($parts[0] == $parts[1]) { $time = $parts; } else { $time = $parts[0] . '-' . $parts[1]; } } else { kohana::log('error', 'Time of day route had no time'); return FALSE; } $weekDayColumns = array('sun', 'mon', 'tue', 'wen', 'thur', 'fri', 'sat'); $wday = ''; foreach ($weekDayColumns as $pos => $weekDayColumn) { if (!empty($destination[$weekDayColumn])) { $wday .= $pos + 1 . ','; } } $wday = rtrim($wday, ','); // TODO: This makes no sense.... if (empty($wday)) { $wday = '1-7'; } $xml->setXmlRoot($xml->getExtensionRoot()); $xml->update('/condition[@wday="' . $wday . '"]{@minute-of-day="' . $time . '"}'); if ($action = fs::getTransferToNumber($destination['during_number_id'])) { $action = str_replace('transfer ', '', $action); $xml->update('/condition[@wday="' . $wday . '"]/action[@application="transfer"]{@data="' . $action . '"}'); } else { $xml->update('/condition[@wday="' . $wday . '"]/action[@application="hangup"]'); } if ($antiAction = fs::getTransferToNumber($destination['outside_number_id'])) { $antiAction = str_replace('transfer ', '', $antiAction); $xml->update('/condition[@wday="' . $wday . '"]/anti-action[@application="transfer"]{@data="' . $antiAction . '"}'); } else { $xml->update('/condition[@wday="' . $wday . '"]/action[@application="hangup"]'); } }
public static function dialplan($number) { $xml = Telephony::getDriver()->xml; $destination = $number['Destination']; if ($destination instanceof ExternalXfer) { $numberOptions = fs::getNumberOptions($number); switch ($destination['route_type']) { case ExternalXfer::TYPE_SIP: if (empty($destination['route_details']['interface']) or empty($destination['route_details']['sipuri'])) { } $dialstring = 'sofia/sipinterface_' . $destination['route_details']['interface'] . '/' . $destination['route_details']['sipuri']; break; case ExternalXfer::TYPE_TRUNK: if (empty($destination['route_details']['trunk']) or empty($destination['route_details']['number'])) { } $dialstring = 'sofia/gateway/trunk_' . $destination['route_details']['trunk'] . '/' . $destination['route_details']['number']; break; } $dialstring = str_replace(array('/', '@'), array('\\/', '\\@'), $dialstring); if (empty($dialstring)) { return; } $xml->update('/action[@application="set"][@bluebox="settingTimeout"]{@data="call_timeout=' . $numberOptions['timeout'] . '"}'); $xml->update('/action[@application="set"][@bluebox="settingRing"]{@data="ringback=' . $numberOptions['ringtype'] . '"}'); $xml->update('/action[@application="set"][@bluebox="settingRingXfer"]{@data="transfer_ringback=' . $numberOptions['ringtype'] . '"}'); if (!empty($destination['plugins']['callerid']['internal_name'])) { $xml->update('/action[@application="export"][@bluebox="sipCalleeIdName"]{@data="sip_callee_id_name=' . $destination['plugins']['callerid']['internal_name'] . '"}'); } else { $xml->update('/action[@application="export"][@bluebox="sipCalleeIdName"]{@data="sip_callee_id_name=' . $destination['name'] . '"}'); } $xml->update('/action[@application="export"][@bluebox="sipCalleeIdNumber"]{@data="sip_callee_id_number=' . $number['number'] . '"}'); $options = array(); if (arr::get($destination, 'registry', 'ignore_early_media')) { $options[] = 'ignore_early_media=true'; } if (arr::get($destination, 'registry', 'require_confirmation')) { $options[] = 'group_confirm_file=ivr\\/ivr-accept_reject_voicemail.wav,group_confirm_key=1,leg_timeout=' . arr::get($destination, 'registry', 'require_confirmation_timeout'); } if (count($options) > 0) { $options = '{' . implode(',', $options) . '}'; } else { $options = ''; } if (($type = arr::get($destination, 'plugins', 'activefeaturecode', 'type')) && arr::get($destination, 'plugins', 'activefeaturecode', 'type') != '0') { switch ($type) { case 'transfer': $fc = arr::get($destination, 'plugins', 'activefeaturecode', 'number'); $ext = arr::get($destination, 'plugins', 'activefeaturecode', 'exten'); $transfer = fs::getTransferToNumber($ext); $leg = arr::get($destination, 'plugins', 'activefeaturecode', 'leg'); $xml->update('/action[@application="set"][@bluebox="afc_app"]{@data="bridge_pre_execute_' . $leg . 'leg_app=bind_digit_action"}'); $xml->update('/action[@application="set"][@bluebox="afc_data"]{@data="bridge_pre_execute_' . $leg . 'leg_data=transfer_back,' . $fc . ',exec:transfer,-bleg ' . $transfer . '"}'); break; default: break; } } $xml->update('/action[@application="bridge"]{@data="' . $options . $dialstring . '"}'); } }
public static function dialplan($number) { $xml = Telephony::getDriver()->xml; $destination = $number['Destination']; if ($destination['timezone'] == '') { $timezone = Kohana::config('locale.timezone'); } else { $timezone = $destination['timezone']; } if (!empty($destination['time'])) { $parts = explode(';', $destination['time']); if (count($parts) != 2) { kohana::log('error', 'Time was not comprised of two parts'); return FALSE; } $time = FreeSwitch_TimeOfDay_Driver::make_range_regex(sprintf("%02d%02d", $parts[0] / 60, $parts[0] % 60), sprintf("%02d%02d", $parts[1] / 60, $parts[1] % 60)); } else { kohana::log('error', 'Time of day route had no time'); return FALSE; } $weekDayColumns = array('mon', 'tue', 'wen', 'thur', 'fri', 'sat', 'sun'); $wday = ''; $comment = ''; foreach ($weekDayColumns as $pos => $weekDayColumn) { if (!empty($destination[$weekDayColumn])) { $wday .= $pos + 1; $comment .= $weekDayColumn . ", "; } } // TODO: This makes no sense.... if (empty($wday)) { $wday = '1-7'; $comment = 'any day, '; } $comment .= sprintf("%02d:%02d - %02d:%02d", $parts[0] / 60, $parts[0] % 60, $parts[1] / 60, $parts[1] % 60); $xml->setXmlRoot($xml->getExtensionRoot()); $cond = '/condition[@field="${strftime_tz(' . str_replace('/', '\\/', $timezone) . ' %u%H%M)}"]'; $xml->update($cond . '{@blueboxcomment="' . $comment . '"}{@expression="^[' . "{$wday}]{$time}" . '"}'); if ($action = fs::getTransferToNumber($destination['during_number_id'])) { $action = str_replace('transfer ', '', $action); $xml->update($cond . '/action[@application="transfer"]{@data="' . $action . '"}'); } else { $xml->update($cond . '/action[@application="hangup"]'); } if ($antiAction = fs::getTransferToNumber($destination['outside_number_id'])) { $antiAction = str_replace('transfer ', '', $antiAction); $xml->update($cond . '/anti-action[@application="transfer"]{@data="' . $antiAction . '"}'); } else { $xml->update($cond . '/anti-action[@application="hangup"]'); } }
/** * Indicate we support FreeSWITCH with this SIP Device and provide code to save SIP device specific settings */ public static function set($base) { $xml = Telephony::getDriver()->xml; // Reference to our XML document, context and extension. Creates the extension & context if does not already exist $xml = FreeSwitch::createExtension('number_' . $base['Number']['number_id'], 'main', 'context_' . $base['context_id']); // Does this number go anywhere? if ($base['Number']['class_type']) { kohana::log('debug', 'FreeSWITCH -> ADDING NUMBER ' . $base['Number']['number'] . ' (' . $base['Number']['number_id'] . ') TO CONTEXT ' . $base['context_id']); // Dialplans are a bit different - we don't want to keep anything that is currently in an extension, in the event it's totally changed $xml->deleteChildren(); // Check what number they dialed $xml->update('/condition[@field="destination_number"]{@expression="^' . $base['Number']['number'] . '$"}'); // Now that the extension and condition fields are created for this number, set our root to inside the condition $xml->setXmlRoot($xml->getXmlRoot() . '/condition[@field="destination_number"][@expression="^' . $base['Number']['number'] . '$"]'); $dialplan = $base['Number']['dialplan']; // Add an extension-specific prenumber items // Note that unlike other dialplan adds, this one assumes you're already in the right spot in the XML document for the add dialplan::preNumber($base['Number']); if (!empty($dialplan['terminate']['action'])) { switch ($dialplan['terminate']['action']) { case 'transfer': $xml->update('/action[@application="set"][@bluebox="settingEndBridge"][@data="hangup_after_bridge=true"]'); $xml->update('/action[@application="set"][@bluebox="settingFail"][@data="continue_on_fail=true"]'); break; } } // Add related final destination XML $destinationDriverName = Telephony::getDriverName() . '_' . substr($base['Number']['class_type'], 0, strlen($base['Number']['class_type']) - 6) . '_Driver'; Kohana::log('debug', 'FreeSWITCH -> Looking for destination driver ' . $destinationDriverName); // Is there a driver? if (class_exists($destinationDriverName, TRUE)) { // Logging Kohana::log('debug', 'FreeSWITCH -> Adding information for destination ' . $base['Number']['number_id'] . ' from model "' . get_class($base['Number']) . '" to our telephony configuration...'); // Drivers are always singletons, and are responsible for persistenting data for their own config generation via static vars // TODO: Change this for PHP 5.3, which doesn't require eval(). Don't change this until all the cool kids are on PHP 5.3*/ kohana::log('debug', 'FreeSWITCH -> EVAL ' . $destinationDriverName . '::dialplan($base->Number);'); $success = eval('return ' . $destinationDriverName . '::dialplan($base->Number);'); } // Add an anti-action / failure route for this dialplan // Note that unlike other dialplan adds, this one assumes you're already in the right spot in the XML document for the add dialplan::postNumber($base['Number']); if (!empty($dialplan['terminate']['action'])) { switch ($dialplan['terminate']['action']) { case 'transfer': if ($transfer = fs::getTransferToNumber($dialplan['terminate']['transfer'])) { $xml->update('/action[@application="transfer"][@data="' . $transfer . '"]'); } else { $xml->update('/action[@application="hangup"]'); } break; case 'continue': break; case 'hangup': default: $xml->update('/action[@application="hangup"]'); break; } } else { $xml->update('/action[@application="hangup"]'); } } else { kohana::log('debug', 'FreeSWITCH -> REMOVING NUMBER ID ' . $base['Number']['number_id'] . ' FROM CONTEXT ' . $base['context_id']); $xml->deleteNode(); } }
private static function createTimeCondition($destination, $wday, $time) { //$xml->update('/condition[@wday="' .$wday .'"]{@minute-of-day="' . $time .'"}'); $wday = preg_replace('/,$/', '', implode(',', $wday)); $xml = '<condition wday="' . $wday . '" minute-of-day="' . $time . '">'; if ($action = fs::getTransferToNumber($destination['during_number_id'])) { $action = str_replace('transfer ', '', $action); //$xml->update('/condition[@wday="' . $wday .'"]/action[@application="transfer"]{@data="' .$action .'"}'); $xml .= '<action application="transfer" data="' . $action . '"/>'; } else { //$xml->update('/condition[@wday="' . $wday .'"]/action[@application="hangup"]'); $xml .= '<action application="hangup"/>'; } $xml .= '</condition>'; return $xml; }