function RenderContent() { echo '<div class="content">' . "\n"; if (isset($this->contentString)) { echo $this->contentString; } if (!empty($this->successScript)) { ?> <script language="JavaScript" type="text/JavaScript"> <?php echo $this->successScript; ?> </script> <?php } if (isset($this->rowString)) { while ($row = $this->qryres->fetchRow()) { echo str_alparams($this->rowString, $row); } } if (isset($this->afterContentString)) { echo $this->afterContentString; } echo '</div>' . "\n"; }
private function genContentElems(&$outstream, &$resr, array $crd, $nnum = NULL) { $n = ''; $line = ''; if (!empty($nnum)) { $n = '_' . $nnum . '_'; } while ($row = $resr->fetchRow()) { $line = '<' . $row['name'] . $n . ' '; if ($row['options'] & 0x1) { $line .= 'ua="rw" '; } else { $line .= 'ua="na"'; } $line .= '> '; $line .= htmlspecialchars(str_alparams($row['valuef'], $crd)); $line .= '</' . $row['name'] . $n . ">\n"; fwrite($outstream, $line); } }
public function genContent(&$outstream) { fwrite($outstream, "; Generated content\n\n"); while ($crd = $this->itemres->fetchRow()) { foreach ($this->grprows as $grp) { $line = ''; $qry = str_dbparams($this->dbhandle, "SELECT * FROM provisions " . "WHERE grp_id = %#1 ORDER BY metric;", array($grp['id'])); $this->out(LOG_DEBUG, "Query: {$qry}"); $pres = $this->dbhandle->Execute($qry); if (!$pres) { $this->out(LOG_ERR, $this->dbhandle->ErrorMsg()); throw new Exception("Cannot locate provision"); } elseif ($itemres->EOF) { $this->out(LOG_WARNING, 'No rows for cc_card'); continue; } // Write a header like [name] .. $line = '['; if (!empty($grp['sub_name'])) { $line .= str_alparams($grp['sub_name'], $crd); } else { $line .= $grp['name']; } $line .= "]\n"; fwrite($outstream, $line); while ($row = $pres->fetchRow()) { $line = ''; if (!empty($row['sub_name'])) { $line = str_alparams($row['sub_name'], $crd); } else { $line = $row['name']; } $line .= '='; $line .= str_alparams($row['valuef'], $crd); $line .= "\n"; fwrite($outstream, $line); } fwrite($outstream, "\n"); } } }
} elseif (!$dialstr) { $last_prob = 'no-dialstring'; continue; } elseif ($dialstr === true) { if (dialSpecial($dialnum, $route, $card, $card_money, $last_prob, $agi, $attempt)) { break; } else { continue; } } if ($special_only) { break; } // Callerid if ($route['clidreplace'] !== NULL) { $new_clid = str_alparams($route['clidreplace'], array('useralias' => $card['useralias'], 'nplan' => $card['numplan'], 'callernum' => $agi->request['agi_callerid'])); } else { $new_clid = $agi->request['agi_callerid']; } if ($route['trunkfmt'] == 15) { // Auto-answer feature for SIP if ($route['providertech'] == 'SIP') { $tmp_add_head = getAGIconfig('auto_answer_' . $route['trunkid'], 'Call-Info: answer-after=0'); //Hack: agi->exec doesn't like spaces, so we include the string into quotes if (strpos($tmp_add_head, ' ') !== FALSE) { $tmp_add_head = '"' . $tmp_add_head . '"'; } if (!empty($tmp_add_head)) { $agi->exec('SIPAddHeader', $tmp_add_head); } } else {
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; }
protected function performSumQuery(&$summ, &$form, &$dbhandle, &$robj) { $robj->debug("ncols:" . $this->ncols); if ($form->FG_DEBUG > 3) { $robj->debug("SumMultiView! Building Sum query.."); } if (empty($summ['fns'])) { $robj->debug("No sum functions!"); return; } $query_fields = array(); $query_outerfields = array(); $query_clauses = array(); $query_grps = array(); $query_table = $form->model_table; $query_outertable = ''; $need_raw = $robj->NeedRaw(); foreach ($form->model as $fld) { $fld->buildSumQuery($dbhandle, $summ['fns'], $query_fields, $query_outerfields, $query_table, $query_outertable, $query_clauses, $query_grps, $form); } if (!strlen($query_table)) { $robj->debug("No sum table!"); return; } $QUERY = 'SELECT '; if (count($query_fields) == 0) { $robj->debug("No sum query fields!"); return; } if (isset($summ['clauses'])) { $query_clauses = array_merge($query_clauses, $summ['clauses']); } $QUERY .= implode(', ', $query_fields); $QUERY .= ' FROM ' . $query_table; if (count($query_clauses)) { $QUERY .= ' WHERE ' . implode(' AND ', $query_clauses); } if (!empty($query_grps) && (!isset($summ['group']) || $summ['group'] != false)) { $QUERY .= ' GROUP BY ' . implode(', ', $query_grps); } //Try to see if we can order if (!empty($form->order)) { if (empty($query_grps) || in_array($form->order, $query_grps)) { $ordert = $form->order; } else { // search again for expressions foreach ($form->model as $fld) { if ($fld->fieldname == $form->order) { if (in_array($fld->fieldexpr, $query_grps)) { $ordert = $fld->fieldexpr; } break; } } } } elseif (!empty($summ['order'])) { $ordert = $summ['order']; } else { $ordert = null; } if (!empty($ordert)) { $QUERY .= " ORDER BY {$ordert}"; if (!empty($form->sens)) { if (strtolower($form->sens) == 'desc') { $QUERY .= " DESC"; } } elseif (!empty($summ['sens']) && strtolower($summ['sens']) == 'desc') { $QUERY .= " DESC"; } } if (!empty($summ['limit'])) { $QUERY .= ' LIMIT ' . $summ['limit']; } $needouter = false; if (!empty($query_outertable)) { $needouter = true; } else { foreach ($query_outerfields as $qof) { if (!is_string($qof)) { $needouter = true; break; } } } if ($needouter) { $qf2 = array(); foreach ($query_outerfields as $qof) { if (is_string($qof)) { $qf2[] = $qof; } elseif (is_array($qof)) { if ($need_raw) { $qf2[] = $qof[1] . ' AS ' . $qof[1] . '_raw'; } $qf2[] = $qof[0] . ' AS ' . $qof[1]; } } $QUERY = 'SELECT ' . implode(', ', $qf2) . ' FROM ' . '(' . $QUERY . ') AS innerfoo ' . $query_outertable; } $QUERY .= ';'; if ($form->FG_DEBUG > 3) { $robj->debug("SUM QUERY: {$QUERY}"); } if (!empty($this->queryreplace)) { $rrep = false; if (isset($this->queryreplace['query'])) { $REPQRY = str_alparams($this->queryreplace['query'], array(clauses => implode(' AND ', $query_clauses), fields => implode(', ', $query_fields), grps => $query_grps, table => $query_table)); if ($form->FG_DEBUG > 3) { $robj->debug("REP QUERY: {$REPQRY}"); } $resRep = $dbhandle->Execute($REPQRY); if (!$resRep) { $robj->debug("RepQuery Failed: " . nl2br(htmlspecialchars($dbhandle->ErrorMsg()))); } else { $rrep = $resRep->fetchRow(); } } if (!$rrep) { $rrep = $this->queryreplace['default']; } $QUERY = str_aldbparams($dbhandle, $QUERY, $rrep); if ($form->FG_DEBUG > 3) { $robj->debug("SUM QUERY after rep: {$QUERY}"); } } // Perform the query $res = $dbhandle->Execute($QUERY); if (!$res) { $robj->debug("Query Failed: " . nl2br(htmlspecialchars($dbhandle->ErrorMsg()))); return; } return $res; }
function Send_Mails($dbg = 1, $dry = false) { $dbhandle = A2Billing::DBHandle(); if ($dbg > 2) { echo "Mailer: start\n"; } $sqlTimeFmt = _("YYYY-MM-DD HH24:MI:SS TZ"); // TODO: not only select, but lock mails in 'sending' state. $qry = "SELECT cc_mailings.id AS id, mtype, fromname, fromemail, subject, \n\t\tmessage, defargs, tomail, args, to_char(tstamp,'{$sqlTimeFmt}') AS mdate\n\t\tFROM cc_templatemail, cc_mailings\n\t\tWHERE cc_mailings.tmail_id = cc_templatemail.id\n\t\tAND (state = 1 OR state = 5);"; $res = $dbhandle->Execute($qry); if (!$res) { if ($dbg > 0) { echo "Query Failed: " . $dbhandle->ErrorMsg() . "\n"; } return false; } elseif ($res->EOF) { if ($dbg > 2) { echo "No mails need to be sent.\n"; } return true; } try { while ($row = $res->fetchRow()) { if ($dbg > 2) { echo "Sending " . $row['mtype'] . " to " . $row['tomail'] . "\n"; } if (empty($row['tomail'])) { if ($dbg > 2) { echo "No recepient specified!\n"; } continue; } $mai = new Mailer(); $mai->setTo('', $row['tomail']); $mai->setFrom($row['fromname'], $row['fromemail']); // Format parameters $defargs = array(); parse_str($row['defargs'], $defargs); $defargs['mdate'] = $row['mdate']; $toargs = array(); parse_str($row['args'], $toargs); $args = array_merge($defargs, $toargs); if ($dbg > 2) { echo "Arguments:"; print_r($args); echo "\n"; } $mai->setSubject(str_alparams($row['subject'], $args), "UTF-8"); $mai->body = new Mailer_TextBody(str_alparams($row['message'], $args)); if ($dry) { $mai->PrintMail(); continue; } try { if ($dbg > 2) { echo "Sending mail.."; } $mai->SendMail(); if ($dbg > 2) { echo " done.\n"; } update_mailing($dbhandle, $row['id'], true, $dbg); } catch (Exception $ex) { if ($dbg > 2) { echo " failed.\n"; } update_mailing($dbhandle, $row['id'], false, $dbg); throw $ex; } } } catch (Exception $ex) { if ($dbg > 1) { echo "Exception: " . $ex->getMessage(); } } return true; }
public function DispList(array &$qrow, &$form) { if (empty($this->href)) { return parent::DispList($qrow, $form); } $msg = ''; if (!empty($this->message)) { $msg = ' title="' . htmlspecialchars($this->message) . '"'; } $href = str_alparams($this->href, $qrow); echo '<a href="' . $href . '"' . $msg . '>'; parent::DispList($qrow, $form); echo '</a>'; }
public function DispList(array &$qrow, &$form) { $act = $form->getAction(); $url = null; $url_tooltip = null; if ($act == 'list' && $this->list_url) { $url = str_alparams($this->list_url, $qrow); } elseif ($act == 'details' && $this->detail_url) { $url = str_alparams($this->detail_url, $qrow); } if ($url) { echo '<a href="' . $url . '" >'; } echo htmlspecialchars($qrow[$this->fieldname . '_' . $this->refname]); if ($this->list_ref && $act == 'list' || $this->detail_ref && $act == 'details') { echo " (" . htmlspecialchars($qrow[$this->fieldname]) . ")"; } else { if ($form->FG_DEBUG > 3) { echo " (Ref:" . htmlspecialchars($qrow[$this->fieldname]) . ")"; } } if ($url) { echo '</a>'; } if ($act == 'list' && $this->tooltip_url) { $url_tooltip = str_alparams($this->tooltip_url, $qrow); echo ' <a href="' . $url_tooltip . '&width=' . $this->width_tooltip . '" '; echo ' class="jTip" id="' . $this->fieldname . '_' . $this->tooltip_id++ . '" name="' . $this->caption_tooltip . '"><b>?</b></a>'; } }
} elseif (!$dialstr) { $last_prob = 'no-dialstring'; continue; } elseif ($dialstr === true) { if ($did_clidname != $agi->request['agi_calleridname']) { $agi->set_variable('CALLERID(name)', $did_clidname); } if (dialSpecial($didrow['dialstring'], $route, $card, $card_money, $last_prob, $agi, $attempt)) { break; } else { continue; } } // Callerid if ($did_clidreplace !== NULL) { $new_clid = str_alparams($did_clidreplace['repl'], array(useralias => $card['useralias'], nplan => $card['numplan'], callernum => $agi->request['agi_callerid'], callern => substr($agi->request['agi_callerid'], $did_clidreplace['find_len']))); } else { $new_clid = $agi->request['agi_callerid']; } // we always reset the clid, because the previous rate // engine may have changed it. $agi->conlog("Setting clid to : \"{$did_clidname}\" <{$new_clid}>", 3); if ($did_clidname != $agi->request['agi_calleridname']) { $agi->set_variable('CALLERID(name)', $did_clidname); } $agi->set_variable('CALLERID(num)', $new_clid); $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, 'did', $agi->request['agi_channel'], $uniqueid, NULL, $agi->request['agi_callerid'], $did_extension, $route['destination'], $route['srid'], $route['brid'], $didrow['tgid'], $route['trunkid'])); if ($notice = $a2b->DBHandle()->NoticeMsg()) { $agi->verbose('DB:' . $notice, 2); } if (!$res) {
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; }