Exemplo n.º 1
0
function getSpeedDial($card, &$dialnum)
{
    global $a2b;
    global $agi;
    // SPEED DIAL HANDLER
    if (($sp_prefix = getAGIconfig('speeddial_prefix', NULL)) != NULL) {
        if (strncmp($dialnum, $sp_prefix, strlen($sp_prefix)) == 0) {
            // translate the speed dial.
            $QRY = str_dbparams($a2b->DBHandle(), "SELECT phone, name FROM speeddials WHERE card_id = %#1 AND speeddial = %2", array($card['id'], substr($dialnum, strlen($sp_prefix))));
            $agi->conlog($QRY, 3);
            $res = $a2b->DBHandle()->Execute($QRY);
            // If the rate engine has anything to Notice/Warn, display that..
            if ($notice = $a2b->DBHandle()->NoticeMsg()) {
                $agi->verbose('DB:' . $notice, 2);
            }
            if (!$res) {
                $agi->verbose('Speed Dial: query error!', 2);
                $agi->conlog($a2b->DBHandle()->ErrorMsg(), 2);
                if (getAGIconfig('say_errors', true)) {
                    $agi->stream_file('allison2', '#');
                }
                break;
            } elseif ($res->EOF) {
                $agi->verbose('Speed Dial: no result.', 2);
            }
            $arr_speeddial = $res->fetchRow();
            $agi->conlog('Speed Dial : found ' . $arr_speeddial['phone'], 4);
            $dialnum = $arr_speeddial['phone'];
        }
    }
}
Exemplo n.º 2
0
    $agi->conlog('Card: ' . print_r($card, true), 4);
    //TODO: fix lang
    if ($card['status'] != 1) {
        switch ($card['status']) {
            case 8:
                //disabled card in booth
                $agi->stream_file('prepaid-no-card-entered', '#');
                break;
            case 5:
                $agi->stream_file('prepaid-card-expired', '#');
                break;
            default:
                $agi->verbose('Card status: ' . $card['status'] . ', exiting.', 2);
        }
        break;
    }
    // Here, we're authorized..
    if (getVoucher($card) !== null) {
        // perhaps stream the credit?
        break;
    }
    // or continue, if voucher didn't succeed.
}
if ($card && !empty($card['locked'])) {
    ReleaseCard($card);
}
$agi->conlog('Goodbye!', 3);
if (getAGIconfig('say_goodbye', true) && $agi->is_alive) {
    $agi->stream_file('prepaid-final', '#');
}
$agi->hangup();
Exemplo n.º 3
0
function formatDialstring_peer($dialn, &$route, &$card, $do_param = true)
{
    global $a2b;
    global $agi;
    $dbhandle = $a2b->DBHandle();
    if ($route['stripdigits'] > 0) {
        $dialnum = substr($route['dialstring'], $route['stripdigits']);
    } else {
        $dialnum = $route['dialstring'];
    }
    $bind_str = '%dialtech/%dialname';
    switch ($route['trunkfmt']) {
        case 4:
            $qry = str_dbparams($dbhandle, 'SELECT dialtech, dialname FROM cc_dialpeer_local_v ' . 'WHERE useralias = %1', array($dialnum));
            $bind_str = '%dialtech/%dialname';
            if (strlen($route['providertech'])) {
                $qry .= str_dbparams($dbhandle, ' AND dialtech = %1', array($route['providertech']));
            }
            // If the trunk specifies an "ip", aliases among the corresponding numplan will be queried
            // else, the numplan *must* be the same with that of the card.
            // It would be wrong not to specify a numplan, since aliases accross them are not unique!
            if (strlen($route['providerip'])) {
                $qry .= str_dbparams($dbhandle, ' AND numplan_name = %1', array($route['providerip']));
            } else {
                $qry .= str_dbparams($dbhandle, ' AND numplan = %#1', array($card['numplan']));
            }
            break;
        case 6:
            // hardcode search into same numplan!
            $qry = str_dbparams($dbhandle, 'SELECT * FROM cc_dialpeer_remote_v ' . 'WHERE useralias = %1 AND numplan = %#2', array($dialnum, $card['numplan']));
            $bind_str = $route['providertech'] . '/' . $route['providerip'];
            break;
        case 7:
        case 15:
            $dnum = explode('-', $dialnum);
            if ($dnum[0] == 'L') {
                $dnum[0] = $card['numplan'];
            }
            $qry = str_dbparams($dbhandle, 'SELECT dialtech, dialname FROM cc_dialpeer_local_v ' . 'WHERE useralias = %2 AND numplan = %#1 ', $dnum);
            if (strlen($route['providertech'])) {
                $qry .= str_dbparams($dbhandle, ' AND dialtech = %1', array($route['providertech']));
            }
            $bind_str = '%dialtech/%dialname';
            $agi->conlog("Query: {$qry}", 3);
            break;
        case 8:
            $dnum = explode('-', $dialnum);
            if ($dnum[0] == 'L') {
                $dnum[0] = $card['numplan'];
            }
            $qry = str_dbparams($dbhandle, 'SELECT * FROM cc_dialpeer_remote_v ' . 'WHERE useralias = %2 AND numplan = %#1', $dnum);
            $agi->conlog("Query: {$qry}", 3);
            $bind_str = $route['providertech'] . '/' . $route['providerip'];
            break;
    }
    $qry .= ';';
    //$agi->conlog("Find peer from ". $qry,4);
    if (!$bind_str) {
        return false;
    }
    $res = $dbhandle->Execute($qry);
    if (!$res) {
        $agi->verbose('Cannot dial peer: ' . $dbhandle->ErrorMsg());
        if (getAGIconfig('say_errors', true)) {
            $agi->stream_file('allison2', '#');
        }
        return false;
    }
    if ($res->EOF) {
        $agi->verbose("Peer dial: cannot find peer " . $dialnum, 2);
        //$agi-> stream_file("prepaid-dest-unreachable",'#');
        return null;
    }
    // Feature! If more than one registrations exist, call all of them in
    // parallel!
    $peer_rows = array();
    while ($row = $res->fetchRow()) {
        $peer_rows[] = str_alparams($bind_str, $row);
    }
    $str = '';
    if ($do_param) {
        if ($agi->astmajor == "1.6") {
            $str .= getAGIconfig('dialcommand_param', ',60,iL(%timeout)%param');
        } else {
            $str .= getAGIconfig('dialcommand_param', '|60|iL(%timeout)%param');
        }
        $str = str_alparams($str, array('dialnum' => $dialnum, 'dialnumber' => $dialn, 'dialstring' => $route['dialstring'], 'destination' => $route['destination'], 'trunkprefix' => $route['trunkprefix'], 'tech' => $route['providertech'], 'providerip' => $route['providerip'], 'prefix' => $route['prefix'], 'param' => $route['trunkparm'], 'cardnum' => $card['username'], 'stimeout' => $route['tmout'], 'timeout' => 1000 * $route['tmout']));
    }
    return implode('&', $peer_rows) . $str;
}
Exemplo n.º 4
0
function getCard_acode()
{
    global $a2b;
    global $agi;
    $dbhandle = $a2b->DBHandle();
    if (!isset($agi->request['agi_accountcode']) || strlen($agi->request['agi_accountcode']) < 3) {
        $agi->verbose("No accountcode for auth", 2);
        return false;
    }
    $acodes = explode(':', $agi->request['agi_accountcode']);
    switch ($acodes[0]) {
        case 'card':
            $res = $dbhandle->Execute('SELECT card.id, tariffgroup AS tgid, card.username, card.status, ' . 'card.numplan, card.useralias, card.features ' . 'FROM cc_card_dv AS card ' . 'WHERE card.id = ? LIMIT 1 ;', array($acodes[1]));
            break;
        case 'booth':
            $res = $dbhandle->Execute('SELECT card.id, tariffgroup AS tgid, card.username, card.status, ' . 'card.numplan, card.useralias, card.features ' . 'FROM cc_card_dv AS card, cc_booth ' . 'WHERE cc_booth.cur_card_id = card.id ' . 'AND cc_booth.id = ? LIMIT 1 ;', array($acodes[1]));
            break;
        case 'remote-agent':
            //used by remote hosts
            $agid = $acodes[1];
            $anivar = $agi->get_variable('CALLERID(ANI)');
            if ($anivar['result'] == 0) {
                $agi->verbose('No ANI set for remote-agent auth');
                return false;
            }
            // TODO: after this, we MUST reset ANI to the proper value, or else
            // we may leak it to the provider!
            $acodes = explode(':', $anivar['data']);
            switch ($acodes[0]) {
                case 'card':
                    $res = $dbhandle->Execute('SELECT card.id, tariffgroup AS tgid, card.username, card.status, ' . 'card.numplan, card.useralias, card.features ' . 'FROM cc_card_dv AS card ' . 'WHERE card.id = ? AND agentid = ? LIMIT 1 ;', array($acodes[1], $agid));
                    break;
                case 'booth':
                    $res = $dbhandle->Execute('SELECT card.id, tariffgroup AS tgid, card.username, card.status, ' . 'card.numplan, card.useralias, card.features ' . 'FROM cc_card_dv AS card, cc_booth ' . 'WHERE cc_booth.cur_card_id = card.id ' . 'AND cc_booth.id = ? AND cc_booth.agentid = ? LIMIT 1 ;', array($acodes[1], $agid));
                    break;
                default:
                    $agi->verbose('Unknown accountcode at remote: ' . $anivar['data']);
                    return false;
            }
            break;
        default:
            $agi->verbose('Unknown accountcode: ' . $agi->request['agi_accountcode']);
            return false;
    }
    if (!$res) {
        $agi->verbose('Cannot auth-acode: ' . $dbhandle->ErrorMsg());
        if (getAGIconfig('say_errors', true)) {
            $agi->stream_file('allison2', '#');
        }
        return false;
    }
    if ($res->EOF) {
        $agi->verbose("Accountcode: no card for " . $acodes[0] . ": " . $acodes[1] . " ", 2);
        if ($acodes[0] == 'booth') {
            $agi->stream_file("prepaid-no-card-entered", '#');
        } else {
            $agi->stream_file("prepaid-auth-fail", '#');
        }
        return false;
    }
    $agi->conlog('Auth-acode: found card.', 4);
    return $res->fetchRow();
}
Exemplo n.º 5
0
/**
 *	Function refill_card_with_voucher
 **/
function getVoucher($card)
{
    global $a2b;
    global $agi;
    $dbhandle = $a2b->DBHandle();
    $agi->conlog('Voucher refill with card', 4);
    $vtimeout = getAGIconfig('voucher-timeoute', 8000);
    $vmaxlen = getAGIconfig('voucher-maxlen', 15);
    $vminlen = getAGIconfig('voucher-minlen', 5);
    $vprompt = getAGIconfig('voucher-prompt', 'prepaid-voucher_enter_number');
    $vprompt_nexist = getAGIconfig('voucher-prompt-nexist', 'prepaid-voucher_does_not_exist');
    $vprompt_refill = getAGIconfig('voucher-prompt-refill', 'prepaid-account_refill');
    $vprompt_no_entered = getAGIconfig('voucher-prompt-no-entered', 'prepaid-no-voucher-entered');
    $vprompt_invalid = getAGIconfig('voucher-prompt-invalid', 'prepaid-invalid-voucher');
    $agi->conlog('Voucher-ivr: asking for Voucher', 4);
    $res_dtmf = $agi->get_data($vprompt, $vtimeout, $vmaxlen);
    $agi->conlog('Voucher-ivr: result ' . print_r($res_dtmf, true), 3);
    if (!isset($res_dtmf['result'])) {
        $agi->conlog('No Voucher entered', 2);
        $agi->stream_file($vprompt_no_entered, '#');
        return null;
    }
    $vouchernum = $res_dtmf['result'];
    if (strlen($vouchernum) < $vminlen || strlen($vouchernum) > $vmaxlen) {
        $agi->conlog('Invalid Voucher', 2);
        $agi->stream_file($vprompt_invalid, '#');
        return null;
    }
    // CALL STORED PROCEDURE FOR VOUCHER
    $QRY = str_dbparams($a2b->DBHandle(), 'SELECT * FROM  card_use_voucher (%1, %2);', array($card['id'], $vouchernum));
    $agi->conlog($QRY, 3);
    $res = $a2b->DBHandle()->Execute($QRY);
    // If the rate engine has anything to Notice/Warn, display that..
    if ($notice = $a2b->DBHandle()->NoticeMsg()) {
        $agi->verbose('DB:' . $notice, 2);
    }
    if (!$res) {
        $emsg = $dbhandle->ErrorMsg();
        if (substr($emsg, 0, 23) == 'ERROR:  card_use_voucher') {
            $msga = explode('|', $emsg);
            $agi->verbose('Could not use voucher: ' . $msga[3]);
            //$agi->conlog("Message: " . print_r($msga,true),4);
            switch ($msga[1]) {
                case 'voucher-no-find':
                    //$agi->stream_file('prepaid-card-in-use','#');
                    break;
                case 'voucher-zero':
                case 'conv_currency-failed':
                case 'conv_currency-failed-zero':
                    //TODO
                    break;
                default:
                    $agi->conlog('Unknown result from card_use_voucher: ' . $msga[1], 3);
            }
        } else {
            $agi->verbose('Could not use voucher : ' . $emsg);
        }
        $agi->stream_file($vprompt_invalid, '#');
        return null;
    }
    if ($res->EOF) {
        $agi->verbose('No used voucher in card_use_voucher(), why?');
        return null;
    }
    $agi->conlog('Unknown result from card_use_voucher: ' . $msga[1], 3);
    $row = $res->fetchRow();
    if (empty($row['card_use_voucher'])) {
        $agi->verbose('Fail to fetch on voucher ! ');
        return false;
    }
    $agi->conlog('Voucher used. Amount of credit added : ' . $row['card_use_voucher'], 3);
    $agi->stream_file($vprompt_refill, '#');
    // TODO : play the Amount of credit added
    return true;
}
Exemplo n.º 6
0
/** Special dial modes, like VoiceMail etc */
function dialSpecial($dialnum, $route, $card, $card_money, &$last_prob, $agi, $attempt)
{
    global $a2b;
    global $mode;
    global $did_clidname;
    global $new_clid;
    $dbhandle = $a2b->DBHandle();
    if ($route['stripdigits'] > 0) {
        $dialnum = substr($route['dialstring'], $route['stripdigits']);
    } else {
        $dialnum = $route['dialstring'];
    }
    $dialn = null;
    switch ($route['trunkfmt']) {
        case 9:
            // Group dial
            require_once "groupdial.inc.php";
            return groupDial($dialnum, $route, $card, $card_money, $last_prob, $agi, $attempt);
            break;
            // group
        // group
        case 10:
            $dialn = array($card['numplan'], $dialnum);
        case 11:
            if (!$dialn) {
                // case 11
                $dialn = explode('-', $dialnum);
                if ($dialn[0] == 'L') {
                    $dialn[0] = $card['numplan'];
                }
            }
            //todo: locale field!
            $qry = str_dbparams($dbhandle, "SELECT email, 'C' AS locale FROM cc_card, cc_card_group\n\t\t\tWHERE cc_card.grp = cc_card_group.id AND cc_card_group.numplan = %#1\n\t\t\t  AND cc_card.useralias = %2 AND cc_card.status =1;", $dialn);
            $res = $dbhandle->Execute($qry);
            if (!$res) {
                $agi->verbose('Cannot query peer: ' . $dbhandle->ErrorMsg());
                return false;
            } else {
                if ($res->EOF) {
                    $agi->conlog("Query: {$qry}", 5);
                    $agi->verbose("Peer email: cannot find peer " . $dialnum, 2);
                    return false;
                }
            }
            $row = $res->fetchRow();
            if (empty($row['email'])) {
                $agi->conlog("User at {$dialnum}, has no email, skipping.", 3);
                return true;
            }
            if (empty($route['providerip'])) {
                $tmpl = 'missed-call';
            } else {
                $tmpl = $route['providerip'];
            }
            // TODO: put more data in params..
            // TODO: do NOT issue callerid, when callingpres prohibits is. It is bad !
            if (!empty($did_clidname)) {
                $clname = $did_clidname;
            } else {
                $clname = $agi->request['agi_calleridname'];
            }
            if (!empty($new_clid)) {
                $clid = $new_clid;
            } else {
                $clid = $agi->request['agi_callerid'];
            }
            $params = array('clid' => $clid, 'agiclid' => $agi->request['agi_callerid'], 'clname' => $clname, 'agiclname' => $agi->request['agi_calleridname'], 'last' => $last_prob);
            $res = $dbhandle->Execute("SELECT create_mail(?,?,?,?);", array($tmpl, $row['email'], $row['locale'], arr2url($params)));
            if (!$res) {
                $agi->verbose('Cannot create mail: ' . $dbhandle->ErrorMsg(), 2);
                return false;
            }
            $str = $dbhandle->NoticeMsg();
            if ($str) {
                $agi->verbose($str, 3);
            }
            // FIXME: how well should the email be quoted before fed to the AGI?
            $agi->conlog("Mail notification queued for " . str_replace("\n", '', $row['email']));
            return true;
        case 12:
            // local voicemail
            $dialn = array($card['numplan'], $dialnum);
        case 13:
            // cross-nplan voicemail
            // We obviously cannot get any voicemail if the caller has
            // hung up.
            if ($last_prob == 'cancel') {
                return false;
            }
            if (!$dialn) {
                // case 11
                $dialn = explode('-', $dialnum);
                if ($dialn[0] == 'L') {
                    $dialn[0] = $card['numplan'];
                }
            }
            //todo: locale field!
            $qry = str_dbparams($dbhandle, "SELECT username, email, 'C' AS locale FROM cc_card, cc_card_group\n\t\t\tWHERE cc_card.grp = cc_card_group.id AND cc_card_group.numplan = %#1\n\t\t\t  AND cc_card.useralias = %2 AND cc_card.status =1;", $dialn);
            $res = $dbhandle->Execute($qry);
            if (!$res) {
                $agi->verbose('Cannot query peer: ' . $dbhandle->ErrorMsg());
                return false;
            } else {
                if ($res->EOF) {
                    $agi->conlog("Query: {$qry}", 5);
                    $agi->verbose("Peer voicemail: cannot find peer " . $dialnum, 2);
                    return false;
                }
            }
            $row = $res->fetchRow();
            $vmcontext = getAGIconfig('vmcontext', 'default');
            $mailbox = $row['username'];
            if (!empty($vmcontext)) {
                $mailbox .= '@' . $vmcontext;
            }
            $agi->conlog("Voicemail for {$mailbox}", 3);
            if ($last_prob == 'busy') {
                $mopts = 'b';
            } else {
                $mopts = 'u';
            }
            $mopts .= $route['trunkparm'];
            // usually, the 's'
            $uniqueid = $agi->request['agi_uniqueid'];
            // . $attempt;
            $res = $a2b->DBHandle()->Execute('INSERT INTO cc_call (cardid, attempt, cmode, ' . 'sessionid, uniqueid, nasipaddress, src, ' . 'calledstation, destination, ' . 'srid, brid, tgid, trunk) ' . 'VALUES( ?,?,?,?,?,?,?,?,?,?,?,?,?) RETURNING id;', array($card['id'], $attempt, $mode, $agi->request['agi_channel'], $uniqueid, NULL, $card['username'], $dialnum, $route['destination'], $route['srid'], $route['brid'], $route['tgid'], $route['trunkid']));
            if ($notice = $a2b->DBHandle()->NoticeMsg()) {
                $agi->verbose('DB:' . $notice, 2);
            }
            if (!$res) {
                $agi->verbose('Cannot mark call start in db!');
                $agi->conlog($a2b->DBHandle()->ErrorMsg(), 2);
                // This error may mean that trunk is in use etc.
                // If call cannot be billed, we'd better abort it.
                $last_prob = 'call-insert';
                return false;
            } elseif ($res->EOF) {
                $agi->verbose('Cannot mark call start in db: EOF!');
                $last_prob = 'call-insert';
                return false;
            }
            $call_id = $res->fetchRow();
            $agires = $agi->exec('VoiceMail', array($mailbox, $mopts));
            // $agi->conlog("VM result: ". print_r($agires,true),5);
            $vmstatus = $agi->get_variable('VMSTATUS');
            $agi->conlog("VM status: " . print_r($vmstatus, true), 5);
            $res = $dbhandle->Execute('UPDATE cc_call SET ' . 'stoptime = now(), sessiontime = EXTRACT(epoch from (now() - starttime))::INTEGER, tcause = ?, hupcause = 0 ' . 'WHERE id = ? ;', array($vmstatus['data'], $call_id['id']));
            if ($notice = $dbhandle->NoticeMsg()) {
                $agi->verbose('DB:' . $notice, 2);
            }
            if (!$res) {
                $agi->verbose('Cannot mark call end in db! (will NOT bill)', 0);
                $agi->conlog($dbhandle->ErrorMsg(), 2);
            } else {
                if ($dbhandle->Affected_Rows() < 1) {
                    $agi->verbose('Could not mark call end! (will NOT bill)', 1);
                }
            }
            if ($vmstatus['data'] != 'SUCCESS') {
                return false;
            }
            // TODO: here, try to create an email with the voicemail...
            /*		if (empty($route['providerip']))
            			$tmpl='missed-call';
            		else
            			$tmpl=$route['providerip'];
            			// TODO: put more data in params..
            			// TODO: do NOT issue callerid, when callingpres prohibits is. It is bad !
            		$params = array( clid => $agi->request['agi_callerid'], clname=> $agi->request['agi_calleridname'],
            			 last => $last_prob);
            		$res = $dbhandle->Execute( "SELECT create_mail(?,?,?,?);",
            			array($tmpl,$row['email'],$row['locale'], arr2url($params)));
            		if (!$res)
            			$agi->verbose('Cannot create mail: '. $dbhandle->ErrorMsg(),2);
            			return false;
            		}
            		$str = $dbhandle->NoticeMsg();
            		if ($str)
            			$agi->verbose($str,3);
            		// FIXME: how well should the email be quoted before fed to the AGI?
            		$agi->conlog("Mail notification queued for ". str_replace("\n",'',$row['email']));
            		*/
            return true;
        case 14:
            // voicemail Main (user's menu)
            $vmcontext = getAGIconfig('vmcontext', 'default');
            $mailbox = $card['username'];
            if (!empty($vmcontext)) {
                $mailbox .= '@' . $vmcontext;
            }
            $agi->conlog("Voicemail Main for {$mailbox}", 3);
            $uniqueid = $agi->request['agi_uniqueid'];
            $res = $a2b->DBHandle()->Execute('INSERT INTO cc_call (cardid, attempt, cmode, ' . 'sessionid, uniqueid, nasipaddress, src, ' . 'calledstation, destination, ' . 'srid, brid, tgid, trunk) ' . 'VALUES( ?,?,\'vm-main\',?,?,?,?,?,?,?,?,?,?) RETURNING id;', array($card['id'], $attempt, $agi->request['agi_channel'], $uniqueid, NULL, $card['username'], $dialnum, $route['destination'], $route['srid'], $route['brid'], $route['tgid'], $route['trunkid']));
            if ($notice = $a2b->DBHandle()->NoticeMsg()) {
                $agi->verbose('DB:' . $notice, 2);
            }
            if (!$res) {
                $agi->verbose('Cannot mark call start in db!');
                $agi->conlog($a2b->DBHandle()->ErrorMsg(), 2);
                // This error may mean that trunk is in use etc.
                // If call cannot be billed, we'd better abort it.
                $last_prob = 'call-insert';
                return false;
            } elseif ($res->EOF) {
                $agi->verbose('Cannot mark call start in db: EOF!');
                $last_prob = 'call-insert';
                return false;
            }
            $call_id = $res->fetchRow();
            $agires = $agi->exec('VoiceMailMain', array($mailbox, $route['trunkparm']));
            // 		$hangupcause=$agi->get_variable('HANGUPCAUSE');
            //
            // 		$answeredtime = $agi->get_variable("ANSWEREDTIME");
            // 		if ($answeredtime['result']== 0)
            // 			$answeredtime['data'] =0;
            // 		$dialstatus = $agi->get_variable("DIALSTATUS");
            //
            // 		$dialedtime = $agi->get_variable("DIALEDTIME");
            // 		if ($dialedtime['result']== 0)
            // 			$dialedtime['data'] =0;
            //
            // 		$agi->conlog("Dial result: ".$dialstatus['data'].'('. $hangupcause['data']. ') after '. $answeredtime['data'].'sec.',2);
            $res = $dbhandle->Execute('UPDATE cc_call SET ' . 'stoptime = now(), sessiontime = EXTRACT(epoch from (now() - starttime))::INTEGER, tcause = \'ANSWER\', hupcause = 0 ' . 'WHERE id = ? ;', array($call_id['id']));
            if ($notice = $dbhandle->NoticeMsg()) {
                $agi->verbose('DB:' . $notice, 2);
            }
            if (!$res) {
                $agi->verbose('Cannot mark call end in db! (will NOT bill)', 0);
                $agi->conlog($dbhandle->ErrorMsg(), 2);
            } else {
                if ($dbhandle->Affected_Rows() < 1) {
                    $agi->verbose('Could not mark call end! (will NOT bill)', 1);
                }
            }
            //if ($vmstatus['data']!='SUCCESS')
            //	return false;
            return true;
        default:
            $agi->verbose("Cannot dial special with format " . $route['trunkfmt'], 3);
            return false;
    }
}
Exemplo n.º 7
0
            }
        }
        //for
    } catch (Exception $ex) {
        // Here we handle signals received
        $agi->verbose("Exception at dial:" . $ex->getMessage());
        @syslog("Exception at dial:" . $ex->getMessage());
        ReleaseCard($card);
        $card = null;
        break;
    }
}
// while
//TODO: set hangup cause accordingly
if ($last_prob) {
    $agi->conlog("Last problem: " . $last_prob, 2);
}
if ($card && !empty($card['locked'])) {
    ReleaseCard($card);
}
if ($last_call) {
    if (empty($last_call['cause_ext'])) {
        $last_call['cause_ext'] = $last_prob;
    }
    releaseCall1($a2b->DBHandle(), $last_call);
}
$agi->conlog('Goodbye!', 3);
if (getAGIconfig('say_did_goodbye', false) && $agi->is_alive) {
    $agi->stream_file('prepaid-final', '#');
}
$agi->hangup();
Exemplo n.º 8
0
function groupDial($dialnum, $route, $card, $card_money, &$last_prob, $agi, $attempt)
{
    global $a2b, $mode;
    // First, parse *our* string, so that we can form the
    // destinations.
    $gstr = $route['providerip'];
    //TODO: need to combine providerIP & dialstring?
    if (empty($gstr)) {
        $gstr = $dialnum;
    }
    $agi->conlog("Group dialnum: \"{$gstr}\"", 5);
    $gdests = groupstr_analyze($gstr);
    // Then, find all rateengine results for each destination
    $QRY = str_dbparams($a2b->DBHandle(), 'SELECT * FROM RateEngine2(%#1, ?, %#2, now(), %3);', array($card['tgid'], $card['numplan'], $card_money['base']));
    $all_routes = array();
    foreach ($gdests as $gdest) {
        $agi->conlog($QRY . " [?= {$gdest}]", 4);
        $res = $a2b->DBHandle()->Execute($QRY, array($gdest));
        // If the rate engine has anything to Notice/Warn, display that..
        if ($notice = $a2b->DBHandle()->NoticeMsg()) {
            $agi->verbose('DB:' . $notice, 2);
        }
        if (!$res) {
            $agi->verbose('Rate engine: query error!', 2);
            $agi->conlog($a2b->DBHandle()->ErrorMsg(), 3);
            break;
        } elseif ($res->EOF) {
            $agi->verbose('Rate engine: no result.', 3);
            continue;
        }
        $routes = $res->GetArray();
        // now, find the first route that might work
        foreach ($routes as $aroute) {
            if ($aroute['tmout'] < getAGIconfig('min_duration_2call', 30)) {
                $agi->conlog('Call will be too short: ', $aroute['tmout'], 4);
                $last_prob = 'min-length';
                continue;
            }
            if ($aroute['tmout'] > getAGIconfig('max_call_duration', 604800)) {
                $aroute['tmout'] = getAGIconfig('max_call_duration', 604800);
                $agi->conlog('Call truncated to: ', $aroute['tmout'], 4);
            }
            // Check if trunk needs a feature subscription
            if (!empty($aroute['trunkfeat'])) {
                // This field comes as a string, convert to array..
                if (!empty($card['features']) && !is_array($card['features'])) {
                    $card['features'] = sql_decodeArray($card['features']);
                }
                if (empty($card['features']) || !in_array($aroute['trunkfeat'], $card['features'])) {
                    if (empty($last_prob)) {
                        $last_prob = 'no-feature';
                    }
                    $agi->conlog("Call is missing feature \"" . $aroute['trunkfeat'] . "\", skipping route.", 3);
                    $agi->conlog("Features: " . print_r($card['features'], true), 4);
                    continue;
                }
                // feature found!
                $agi->conlog('Call using feature: ' . $aroute['trunkfeat'], 5);
            }
            $dialstr = formatDialstring($dialnum, $aroute, $card, false);
            if ($dialstr === null) {
                $last_prob = 'unreachable';
                continue;
            } elseif (!$dialstr) {
                $last_prob = 'no-dialstring';
                continue;
            } elseif ($dialstr === true) {
                // We cannot use other special trunks in group.
                continue;
            }
            if ($aroute['clidreplace'] !== NULL && $mode != 'did') {
                $new_clid = str_alparams($aroute['clidreplace'], array('useralias' => $card['useralias'], 'nplan' => $card['numplan'], 'callernum' => $agi->request['agi_callerid']));
            } else {
                $new_clid = $agi->request['agi_callerid'];
            }
            // add this route to the available ones
            $all_routes[] = array('r' => $aroute, 'str' => $dialstr, 'clid' => $new_clid);
            //but then, discard all other possibilities for this destination.
            break;
        }
    }
    //$agi->conlog("Group dialing routes: ".print_r($all_routes,true),4);
    if (empty($all_routes)) {
        $last_prob = 'call-fail';
        return false;
    }
    // Now, iterate over all the routes to find some useful stuff
    $agg_route = array();
    $agg_strs = array();
    foreach ($all_routes as $aroute) {
        // Try to have a common CLID.
        if (!isset($agg_route['clid'])) {
            $agg_route['clid'] = $aroute['clid'];
        } elseif ($agg_route['clid'] != $aroute['clid']) {
            $agg_route['clid'] = '';
        }
        if (!isset($agg_route['tmout'])) {
            $agg_route['tmout'] = $aroute['r']['tmout'];
        } elseif ($agg_route['tmout'] > $aroute['r']['tmout']) {
            $agg_route['tmout'] = $aroute['r']['tmout'];
        }
        $agg_strs[] = $aroute['str'];
    }
    $agg_route['str'] = implode('&', $agg_strs);
    //$agi->conlog("Group dialing routes: ".print_r($agg_route,true),4);
    $dialstr = $agg_route['str'] . str_alparams(getAGIconfig('dialcommand_group_param', '|60|iL(%timeout)%param'), array('dialstring' => $agg_route['str'], 'trunkprefix' => $route['trunkprefix'], 'tech' => $route['providertech'], 'providerip' => $route['providerip'], 'prefix' => $route['prefix'], 'param' => $route['trunkparm'], 'cardnum' => $card['username'], 'stimeout' => $route['tmout'], 'timeout' => 1000 * $route['tmout']));
    // Place the call!
    $agi->conlog("Setting clid to : " . $agg_route['clid'], 3);
    $agi->set_variable('CALLERID(num)', $agg_route['clid']);
    if (!empty($route['call_uniqueid'])) {
        $uniqueid = $route['call_uniqueid'];
    } else {
        // Construct a unique id with .. + trunkid.
        $uniqueid = $agi->request['agi_uniqueid'] . '-' . $route['trunkid'];
    }
    $res = $a2b->DBHandle()->Execute('INSERT INTO cc_call (cardid, attempt, cmode, ' . 'sessionid, uniqueid, nasipaddress, src, ' . 'calledstation, destination, ' . 'srid, brid, tgid, trunk) ' . 'VALUES( ?,?,?,?,?,?,?,?,?,?,?,?,?) RETURNING id;', array($card['id'], $attempt, $mode, $agi->request['agi_channel'], $uniqueid, NULL, $card['username'], $dialnum, $route['destination'], $route['srid'], $route['brid'], $route['tgid'], $route['trunkid']));
    if ($notice = $a2b->DBHandle()->NoticeMsg()) {
        $agi->verbose('DB:' . $notice, 2);
    }
    if (!$res) {
        $agi->verbose('Cannot mark call start in db!');
        $agi->conlog($a2b->DBHandle()->ErrorMsg(), 2);
        // This error may mean that trunk is in use etc.
        // If call cannot be billed, we'd better abort it.
        $last_prob = 'call-insert';
        return false;
    } elseif ($res->EOF) {
        $agi->verbose('Cannot mark call start in db: EOF!');
        $last_prob = 'call-insert';
        return null;
    }
    $call_id = $res->fetchRow();
    $agi->conlog('Start call ' . $call_id['id'], 4);
    $agi->conlog("Dial group@" . $route['trunkcode'] . " : {$dialstr}", 3);
    $attempt++;
    $call_res = $agi->exec('Dial', $dialstr);
    //TODO: if record, stop
    $hangupcause = $agi->get_variable('HANGUPCAUSE');
    $answeredtime = $agi->get_variable("ANSWEREDTIME");
    if (empty($answeredtime['data']) || $answeredtime['result'] == 0) {
        $answeredtime['data'] = 0;
    }
    $dialstatus = $agi->get_variable("DIALSTATUS");
    $dialedtime = $agi->get_variable("DIALEDTIME");
    if ($dialedtime['result'] == 0) {
        $dialedtime['data'] = 0;
    }
    // We are special, we need to learn who answered here!
    $dialedpeer = $agi->get_variable("DIALEDPEERNUMBER");
    $agi->conlog("Group result: " . $dialstatus['data'] . '@' . $dialedpeer['data'] . '(' . $hangupcause['data'] . ') after ' . $answeredtime['data'] . 'sec.', 2);
    //$agi->conlog("After dial, answertime: ".print_r($answeredtime,true));
    //TODO: SIP, ISDN extended status
    $can_continue = false;
    $cause_ext = '';
    switch ($dialstatus['data']) {
        case 'BUSY':
            $last_prob = 'busy';
            break;
        case 'ANSWERED':
        case 'ANSWER':
        case 'CANCEL':
            // Now, try to see who answered
            if (!empty($dialedpeer['data'])) {
                $agi->conlog("Searching who answered..", 4);
                foreach ($all_routes as $aroute) {
                    $pos = strpos($aroute['str'], '/');
                    if ($pos === false) {
                        $str2 = $aroute['str'];
                    } else {
                        $str2 = substr($aroute['str'], $pos + 1);
                    }
                    if ($dialedpeer['data'] == $str2) {
                        $agi->conlog("Found: " . $aroute['str'], 4);
                        $route = $aroute['r'];
                        break;
                    }
                }
            }
            $last_prob = '';
            break;
        case 'CONGESTION':
        case 'CHANUNAVAIL':
            $last_prob = 'call-fail';
            $can_continue = true;
            break;
        case 'NOANSWER':
            $last_prob = 'no-answer';
            $can_continue = true;
            break;
        default:
            $agi->verbose("Unknown status: " . $dialstatus['data'], 2);
    }
    $res = $a2b->DBHandle()->Execute('UPDATE cc_call SET ' . 'stoptime = now(), sessiontime = ?, tcause = ?, hupcause = ?, ' . 'cause_ext =?, startdelay =?, ' . 'destination =?, srid =?, brid = ?, trunk =? ' . 'WHERE id = ? ;', array($answeredtime['data'], $dialstatus['data'], $hangupcause['data'], $cause_ext, $dialedtime['data'] - $answeredtime['data'], $route['destination'], $route['srid'], $route['brid'], $route['trunkid'], $call_id['id']));
    if ($notice = $a2b->DBHandle()->NoticeMsg()) {
        $agi->verbose('DB:' . $notice, 2);
    }
    if (!$res) {
        $agi->verbose('Cannot mark call end in db! (will NOT bill)', 0);
        $agi->conlog($a2b->DBHandle()->ErrorMsg(), 2);
    }
    return !$can_continue;
}