Exemplo n.º 1
0
function gs_extstate($host, $exts)
{
    static $hosts = array();
    if (!is_array($exts)) {
        $exts = array($exts);
        $return_single = true;
    } else {
        $return_single = false;
    }
    if (gs_get_conf('GS_INSTALLATION_TYPE_SINGLE')) {
        $host = '127.0.0.1';
    }
    if (!isset($hosts[$host])) {
        $hosts[$host] = array('sock' => null, 'lasttry' => 0);
    }
    if (!is_resource($hosts[$host]['sock'])) {
        if ($hosts[$host]['lasttry'] > time() - 60) {
            # we have tried less than a minute ago
            $hosts[$host]['lasttry'] = time();
            return $return_single ? AST_MGR_EXT_UNKNOWN : array();
        }
        $hosts[$host]['lasttry'] = time();
        $sock = @fSockOpen($host, 5038, $err, $errMsg, 2);
        if (!is_resource($sock)) {
            gs_log(GS_LOG_WARNING, 'Connection to AMI on ' . $host . ' failed');
            return $return_single ? AST_MGR_EXT_UNKNOWN : array();
        }
        $data = _sock_read($sock, 3, '/[\\r\\n]/');
        if (!preg_match('/^Asterisk [^\\/]+\\/(\\d(?:\\.\\d)?)/mis', $data, $m)) {
            gs_log(GS_LOG_WARNING, 'Incompatible Asterisk manager interface on ' . $host);
            $m = array(1 => '0.0');
        } else {
            if ($m[1] > '1.1') {
                # Asterisk 1.4: manager 1.0
                # Asterisk 1.6: manager 1.1
                gs_log(GS_LOG_NOTICE, 'Asterisk manager interface on ' . $host . ' speaks a new protocol version (' . $m[1] . ')');
                # let's try anyway and hope to understand it
            }
        }
        $hosts[$host]['sock'] = $sock;
        $req = "Action: Login\r\n" . "Username: "******"gscc" . "\r\n" . "Secret: " . "gspass" . "\r\n" . "Events: off\r\n" . "\r\n";
        @fWrite($sock, $req, strLen($req));
        @fFlush($sock);
        $data = _sock_read($sock, 3, '/\\r\\n\\r\\n/S');
        if ($data === false) {
            gs_log(GS_LOG_WARNING, 'Authentication to AMI on ' . $host . ' failed (timeout)');
            $hosts[$host]['sock'] = null;
            return $return_single ? AST_MGR_EXT_UNKNOWN : array();
        } elseif (!preg_match('/Authentication accepted/i', $data)) {
            gs_log(GS_LOG_WARNING, 'Authentication to AMI on ' . $host . ' failed');
            $hosts[$host]['sock'] = null;
            return $return_single ? AST_MGR_EXT_UNKNOWN : array();
        }
    } else {
        $sock = $hosts[$host]['sock'];
    }
    $states = array();
    foreach ($exts as $ext) {
        $req = "Action: ExtensionState\r\n" . "Context: to-internal-users\r\n" . "Exten: " . $ext . "\r\n" . "\r\n";
        @fWrite($sock, $req, strLen($req));
        @fFlush($sock);
        $resp = trim(_sock_read($sock, 3, '/\\r\\n\\r\\n/S'));
        //echo "\n$resp\n\n";
        $states[$ext] = AST_MGR_EXT_UNKNOWN;
        if (!preg_match('/^Response:\\s*Success/is', $resp)) {
            continue;
        }
        if (!preg_match('/^Exten:\\s*([\\da-z]+)/mis', $resp, $m)) {
            continue;
        }
        $resp_ext = $m[1];
        if (!preg_match('/^Status:\\s*(-?\\d+)/mis', $resp, $m)) {
            continue;
        }
        $resp_state = (int) $m[1];
        $states[$resp_ext] = $resp_state;
    }
    if ($return_single) {
        return array_key_exists($exts[0], $states) ? $states[$exts[0]] : AST_MGR_EXT_UNKNOWN;
    } else {
        return $states;
    }
}
Exemplo n.º 2
0
function gs_queue_status($host, $ext, $getMembers, $getCallers)
{
    static $hosts = array();
    if (gs_get_conf('GS_INSTALLATION_TYPE_SINGLE')) {
        $host = '127.0.0.1';
    }
    if (!isset($hosts[$host])) {
        $hosts[$host] = array('sock' => null, 'lasttry' => 0);
    }
    if (!is_resource($hosts[$host]['sock'])) {
        if ($hosts[$host]['lasttry'] > time() - 60) {
            # we have tried less than a minute ago
            $hosts[$host]['lasttry'] = time();
            return false;
        }
        $hosts[$host]['lasttry'] = time();
        $sock = @fSockOpen($host, 5038, $err, $errMsg, 2);
        if (!is_resource($sock)) {
            gs_log(GS_LOG_WARNING, 'Connection to AMI on ' . $host . ' failed');
            return false;
        }
        $data = _sock_read($sock, 3, '/[\\r\\n]/');
        if (!preg_match('/^Asterisk [^\\/]+\\/(\\d(?:\\.\\d)?)/mis', $data, $m)) {
            gs_log(GS_LOG_WARNING, 'Incompatible Asterisk manager interface on ' . $host);
            $m = array(1 => '0.0');
        } else {
            if ($m[1] > '1.1') {
                # Asterisk 1.4: manager 1.0
                # Asterisk 1.6: manager 1.1
                gs_log(GS_LOG_NOTICE, 'Asterisk manager interface on ' . $host . ' speaks a new protocol version (' . $m[1] . ')');
                # let's try anyway and hope to understand it
            }
        }
        $hosts[$host]['sock'] = $sock;
        $req = "Action: Login\r\n" . "Username: "******"gscc" . "\r\n" . "Secret: " . "gspass" . "\r\n" . "Events: off\r\n" . "\r\n";
        @fWrite($sock, $req, strLen($req));
        @fFlush($sock);
        $data = _sock_read2($sock, 5, '/\\r\\n\\r\\n/S');
        if (!preg_match('/Authentication accepted/i', $data)) {
            gs_log(GS_LOG_WARNING, 'Authentication to AMI on ' . $host . ' failed');
            $hosts[$host]['sock'] = null;
            return false;
        }
    } else {
        $sock = $hosts[$host]['sock'];
    }
    $queue_stats = array('maxlen' => null, 'calls' => null, 'holdtime' => null, 'completed' => null, 'abandoned' => null, 'sl' => null, 'slp' => null);
    if ($getMembers) {
        $queue_stats['members'] = array();
    }
    if ($getCallers) {
        $queue_stats['callers'] = array();
    }
    $default_member = array('dynamic' => null, 'calls' => null, 'lastcall' => null, 'devstate' => null, 'paused' => null);
    $default_caller = array('channel' => null, 'cidnum' => null, 'cidname' => null, 'wait' => null);
    $req = "Action: QueueStatus\r\n" . "Queue: " . $ext . "\r\n" . "\r\n";
    @fWrite($sock, $req, strLen($req));
    @fFlush($sock);
    $resp = trim(_sock_read2($sock, 2, '/Event:\\s*QueueStatusComplete\\r\\n\\r\\n/i'));
    //echo "\n$resp\n\n";
    if (!preg_match('/^Response:\\s*Success/is', $resp)) {
        return false;
    }
    $resp = preg_split('/\\r\\n\\r\\n/S', $resp);
    /*
    echo "<pre>";
    print_r($resp);
    echo "</pre>";
    */
    $manager_ok = false;
    foreach ($resp as $pkt) {
        $pkt = lTrim($pkt);
        if (preg_match('/^Event:\\s*QueueParams/is', $pkt)) {
            if (!preg_match('/^Queue:\\s*' . $ext . '/mis', $pkt)) {
                continue;
            }
            //echo $pkt, "\n\n";
            if (preg_match('/^Max:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['maxlen'] = (int) $m[1] > 0 ? (int) $m[1] : null;
            }
            if (preg_match('/^Calls:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['calls'] = (int) $m[1];
            }
            if (preg_match('/^Holdtime:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['holdtime'] = (int) $m[1];
            }
            if (preg_match('/^Completed:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['completed'] = (int) $m[1];
            }
            if (preg_match('/^Abandoned:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['abandoned'] = (int) $m[1];
            }
            if (preg_match('/^ServiceLevel:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['sl'] = (int) $m[1];
            }
            if (preg_match('/^ServiceLevelPerf:\\s*(\\d+?(\\.\\d+)?)/mis', $pkt, $m)) {
                $queue_stats['slp'] = (double) $m[1];
            }
            $manager_ok = true;
        } elseif ($getMembers && preg_match('/^Event:\\s*QueueMember/is', $pkt)) {
            if (!preg_match('/^Queue:\\s*' . $ext . '/mis', $pkt)) {
                continue;
            }
            if (!preg_match('/^Location:\\s*([A-Z\\d\\/]+)/mis', $pkt, $m)) {
                continue;
            }
            $loc = $m[1];
            $queue_stats['members'][$loc] = $default_member;
            //echo $pkt, "\n\n";
            if (preg_match('/^Membership:\\s*([a-z]+)/mis', $pkt, $m)) {
                $queue_stats['members'][$loc]['dynamic'] = $m[1] != 'static';
            }
            if (preg_match('/^CallsTaken:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['members'][$loc]['calls'] = (int) $m[1];
            }
            if (preg_match('/^LastCall:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['members'][$loc]['lastcall'] = (int) $m[1];
            }
            if (preg_match('/^Status:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['members'][$loc]['devstate'] = (int) $m[1];
            }
            if (preg_match('/^Paused:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['members'][$loc]['paused'] = (int) $m[1] > 0;
            }
        } elseif ($getCallers && preg_match('/^Event:\\s*QueueEntry/is', $pkt)) {
            if (!preg_match('/^Queue:\\s*' . $ext . '/mis', $pkt)) {
                continue;
            }
            if (!preg_match('/^Position:\\s*(\\d+)/mis', $pkt, $m)) {
                continue;
            }
            $pos = (int) $m[1];
            $queue_stats['callers'][$pos] = $default_caller;
            //echo $pkt, "\n\n";
            if (preg_match('/^Channel:\\s*([^\\n\\r]+)/mis', $pkt, $m)) {
                $queue_stats['callers'][$pos]['dynamic'] = trim($m[1]);
            }
            if (preg_match('/^CallerID:\\s*([^\\n\\r]+)/mis', $pkt, $m)) {
                $queue_stats['callers'][$pos]['cidnum'] = strToLower(trim($m[1])) != 'unknown' ? trim($m[1]) : null;
            }
            if (preg_match('/^CallerIDName:\\s*([^\\n\\r]+)/mis', $pkt, $m)) {
                $queue_stats['callers'][$pos]['cidname'] = strToLower(trim($m[1])) != 'unknown' ? trim($m[1]) : null;
            }
            if (preg_match('/^Wait:\\s*(\\d+)/mis', $pkt, $m)) {
                $queue_stats['callers'][$pos]['wait'] = (int) $m[1];
            }
        }
    }
    if (!$manager_ok && $getMembers) {
        # failed to get information about the queue from the manager
        # interface. this happens after a reload of Asterisk when
        # no call has entered the queue using Queue() yet
        $queue_stats['calls'] = 0;
        $queue_stats['completed'] = 0;
        $queue_stats['abandoned'] = 0;
        $queue_stats['holdtime'] = 0;
        include_once GS_DIR . 'inc/db_connect.php';
        $db = @gs_db_slave_connect();
        if (!$db) {
            return $queue_stats;
        }
        $maxlen = (int) $db->executeGetOne('SELECT `maxlen` FROM `ast_queues` WHERE `name`=\'' . $db->escape($ext) . '\'');
        $queue_stats['maxlen'] = $maxlen > 0 ? $maxlen : null;
        $rs = $db->execute('SELECT `interface` FROM `ast_queue_members` WHERE `queue_name`=\'' . $db->escape($ext) . '\'');
        $queue_members = array();
        while ($r = $rs->fetchRow()) {
            if (strToUpper(subStr($r['interface'], 0, 4)) == 'SIP/') {
                $queue_members[] = subStr($r['interface'], 4);
            } else {
                $queue_members[] = $r['interface'];
            }
        }
        if (count($queue_members) < 1) {
            return $queue_stats;
        }
        foreach ($queue_members as $queue_member) {
            $queue_stats['members']['SIP/' . $queue_member] = $default_member;
        }
        $ext_states = @gs_extstate($host, $queue_members);
        if (!is_array($ext_states)) {
            return $queue_stats;
        }
        foreach ($queue_members as $queue_member) {
            $queue_stats['members']['SIP/' . $queue_member]['devstate'] = extstate_to_devstate(@$ext_states[$queue_member]);
        }
    }
    /*
    echo "<pre>";
    print_r($queue_stats);
    echo "</pre>";
    */
    return $queue_stats;
}