Для того, чтобы выполнить запрос из консоли Asterisk (asterisk -rx «»), который установлен на шлюз, или через Web-интерфейс (Дополнительно→Asterisk CLI) то будет доступен только Master модуль. Чтобы работать со Slave модулями, нужно поднимать дополнительное соединение. Как же работает Web-интерфейс с Slave модулями? Так и работает! Если подключиться по ssh к шлюзу, перейти по /web/www/cgi-bin/php/, и проанализировать любой файл, то будет видно, что в качестве параметра скрипт принимает имя порта — gsm-3.4 («gsm-» — шапка названия, «3» — номер модуля, «4» — порт\span). После чего, он определяет к какому модулю нужно подключиться. Если к 1 (master) — то будет выполняться стандартный запрос, типа:

1
$astcmd = "asterisk -rx \"gsm $gsmcmd $i \\\"$cmd\\\" $hangup $timeout \" 2> /dev/null";

Если номер модуля больше\равно 2 (slave), тогда из функции get_cluster_info(), вытаскиваем внутренний IP Slave модуля, формируем запрос типа:

1
$data = "astcmd:gsm $gsmcmd $i \\\"$cmd\\\" $hangup $timeout\n";

И передаем эти данные функции request_slave():

1
$outvalue = request_slave($ip, $data, intval($timeout/1000)+1);

Также есть глобальные переменные, основные с каких:
"global $__GSM_SUM__" — максимальное количество span-ов, которое поддерживает установленный модуль;
"global $__GSM_HEAD__" — шапка названия gsm портов;
"global $__BRD_SUM__" — максимальное количество модулей, которое поддерживает Openvox;
"global $__BRD_HEAD__" — шапка названия модулей.
Для примера работы, приведу скрипт для выполнения ussd запроса:
создадим на рабочем компьютере файл send-ussd.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
include_once("/www/cgi-bin/inc/function.inc");
include_once("/www/cgi-bin/inc/cluster.inc");
include_once("/www/cgi-bin/inc/wrcfg.inc");
    global $__GSM_SUM__;
    global $__BRD_SUM__;
    global $__BRD_HEAD__;
    global $__GSM_HEAD__;
    global $HEAD;
 
function parse_port_name($str)
{
    preg_match_all('/(\b(gsm-)(\d+)[.](\d+))/',$str,$arr);
    if(!empty($arr[0])&&(((intval($arr[3][0])<=intval($GLOBALS["__BRD_SUM__"]))&&(intval($arr[3][0])>0))&&((intval($arr[4][0])<=intval($GLOBALS["__GSM_SUM__"]))&&(intval($arr[4][0])>0))))
        return array('port_name' => $arr[1][0], 'gms_head' => $arr[2][0] ,'board_number' => $arr[3][0], 'gms_number'=>$arr[4][0]);
    else return NULL;
}
 
function is_receive_ussd($ussd_code)
{
    if(isset($ussd_code[0]) && $ussd_code[0] == '1') {
        return true;
    }
 
    return false;
}
function parse_ussd($ussd_code)
{
    //Receive USSD format
    //1:Receive USSD on span 2,reponses:2,code:15
    //Text:ussd code
 
    if(isset($ussd_code[0]) && $ussd_code[0] == '1') {
        $valid_str = substr($ussd_code,strpos($ussd_code,"\n")+1);
        if(strlen($valid_str) > strlen("Text:") ) {
            return substr($valid_str,strlen("Text:"));
        }
    }
    return $ussd_code;
}
if($_GET) {
    if(isset($_GET['portname']) && isset($_GET['ussd'])) {
        $cluster_info = get_cluster_info();
        $port_name=$_GET['portname'];
        $ussd=urldecode($_GET['ussd']);
        $ret=parse_port_name($port_name);
        if(isset($ret)) {
            //echo json_encode($ret);
            $timeout=10000;
            $span=$ret['gms_number'];
 
            if($ret['board_number']=="1"){
            //  echo '</br>master board</br>';
                $data = "asterisk -rx \"gsm send ussd $span \\\"$ussd\\\"  $timeout \" 2> /dev/null";
                $outvalue = get_exec($data);
                for($a=0; $a<3; $a++) {//Max resend
                    if(is_receive_ussd($outvalue)) {
                        $outvalue = parse_ussd($outvalue);
                        break;
                    }
                    $outvalue = get_exec($data);
                }
                echo json_encode($outvalue);
            }
            else {
                //echo '</br>slave board</br>';
                if(isset($cluster_info[$__BRD_HEAD__.$ret['board_number'].'_ip']) && $cluster_info[$__BRD_HEAD__.$ret['board_number'].'_ip'] != '') {
                    $ip=$cluster_info[$__BRD_HEAD__.$ret['board_number'].'_ip'];
                    $data = "astcmd:gsm send ussd $span \\\"$ussd\\\"  $timeout\n";
                    echo 'ip='.$ip.' span='.$span.' data='.$data;
                    $outvalue = request_slave($ip, $data, intval($timeout/1000)+1);
                    if(!$outvalue) {
                        $outvalue = "TIMEOUT";
                    }
                    for($a=0; $a<3; $a++) {//Max resend
                        if(is_receive_ussd($outvalue)) {
                            $outvalue = parse_ussd($outvalue);
                            break;
                        }
                        $outvalue = request_slave($ip, $data, intval($timeout/1000)+1);
                        if(!$outvalue) {
                            $outvalue = "TIMEOUT";
                        }
                    }
                    echo json_encode($outvalue);   
                }
                else echo 'No active board number '.$ret['board_number'];
            }
        }
        else echo 'Edit to format: gsm-(1-'.$__BRD_SUM__.').(1-'.$__GSM_SUM__.')';
    }
    else echo 'Edit Parameters';
}
else echo 'Edit Parameters';
 
?>

Качаем и устанавливаем приложение WinSCP, запускаем его и создаем новое соединение по протоколу SCP. Вводим данные для подключения к ssh. Бросаем файл send-ussd.php в каталог /web/www/cgi-bin/php/, переходим к браузеру, и вводим ссылку http://IP-шлюза/cgi-bin/php/send-ussd.php?portname=gsm-2.4&ussd=%2A111%23 (ussd запрос должен быть URL-кодирован, например пропущен через функцию php urlencode(). В примере ссылки будет выполнен ussd-запрос *111#).

Скрипт проверен на Openvox-ах VS_USB-1020, VS-GGU-E2M0400.