В прошлом году Digium порадовал нас новыми IP телефонами, созданными специально для Asterisk, а также семейством шлюзов TDM-SIP.
Это было два новых устройства: G100 и G200, на один E1 порт, и два E1 порта соответственно.
Достаточно недорогие, и как оказалось стабильные, эти шлюзы проявили себя только с лучшей стороны. С легкостью дружат с Avaya-ми, Panasonic-ами, Asterisk-ом само собой… Да что уж там, PRI он и в Африке PRI :)
Производитель на этом не остановился, и сегодня я рад Вам представить пополнение в линейке шлюзов от Digium. G400 и Digium G800, и как Вы могли догадаться на 4 и… 8 (!) E1 портов.
Технические подробности
Как Вы можете увидеть, исполнение не изменилось. Это половинчатая, 1U коробка для установку в стойку. Без движущихся частей.
Построена на Asterisk, но имеющая веб-интерфейс для управления. Эхоподавление встроено.
Можно подключать неограниченное количество SIP транков, но следует учитывать, что количество максимальных одновременных разговоров (как при G711, так и G729) следующие: G100: 30, G200: 60, G400: 120, G800: 240.
Как Вы могли заметить, на шлюзах теперь два LAN порта (На G100 и G200 был один).
Пока не могу сказать, что данное устройство может быть не только VoIP маршрутизатором, но и маршрутизатором сети. Но два IP интерфейса шлюз точно поддерживает, и есть возможность назначить по два VLAN-а на один физический порт (любой из 4096 Vlan tag выставляется через GUI).
Даташит — docs.digium.com
Gateway API
Интересная фича, которой обладают очень мало продуктов, я бы даже сказал, что никто не обладает (поправьте, если ошибаюсь).
Посредством HTTPS запросов и JSON ответов шлюза, Вы сможете общаться с устройством и производить его полную настройку и диагностику.
Пример кода на PHP для получения аптайма
Раскрыть
<?
$GATEWAY_IP = 'CHANGEME';
$USERNAME = 'admin';
$PASSWORD = 'admin';
$ch = curl_init();
$fields = array(
'admin_uid' => $USERNAME,
'admin_password' => $PASSWORD
);
curl_setopt($ch, CURLOPT_URL, "https://$GATEWAY_IP/admin/main.html");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '');
$result = curl_exec($ch);
if ($result === false) {
$error = curl_error($ch);
curl_close($ch);
die("Login failed: $error");
}
if (preg_match("/Welcome,\\s+$USERNAME/i", $result) == 0
|| preg_match("/Log Out/i", $result) == 0) {
curl_close($ch);
die("Login Failed!");
}
$request = array(
'request' => array(
'method' => 'gateway_list',
'parameters' => array()
)
);
$string = json_encode($request, JSON_FORCE_OBJECT);
$fields = array(
'request' => $string
);
curl_setopt($ch, CURLOPT_URL, "https://$GATEWAY_IP/json");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if ($result === false) {
$error = curl_error($ch);
curl_close($ch);
die("Request failed: $error");
}
curl_close($ch);
$response = json_decode($result);
$response_object = json_decode($response->response->result);
print $response_object->gateway->model_name; print "\n";
print "Uptime "; print $response_object->gateway->uptime; print "\n";
?>
Или через PERL получить информацию об устройстве, и отключить его
Вот так
#!/usr/bin/perl
use strict;
use HTTP::Cookies;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my $ua = new LWP::UserAgent;
# Sometimes both of these are required
my $cookies = new HTTP::Cookies();
$ua->cookie_jar($cookies);
$ua->ssl_opts({'verify_hostname' => 0});
my $GATEWAY_IP = 'CHANGEME';
my $USERNAME = 'admin';
my $PASSWORD = 'admin';
# log in
my $response = $ua->post("https://$GATEWAY_IP/admin/main.html", {
admin_uid => $USERNAME,
admin_password => $PASSWORD,
act => 'login',
});
my $content = $response->content;
print $content;
# Response from login is HTML page, check that the main page init()
# function is called to be sure we have logged in and are looking at
# the main page.
if ($content !~ m/Welcome,\s+$USERNAME/i || $content !~ m/Log Out/i) {
print "Login Failed!\n";
exit 1;
}
# get software version
my $params = { 'request' => {
'method' => 'gateway_list',
'parameters' => { }
}};
$response = $ua->post("https://$GATEWAY_IP/json", {
'request' => JSON->new->utf8->encode($params)
});
# Response from non-login requests are JSON and must be decoded twice
# as follows:
$content = JSON->new->utf8->decode($response->content);
my $res = JSON->new->utf8->decode($content->{'response'}{'result'});
# Uncomment this to see all available information
#print Data::Dumper::Dumper($res);
print sprintf("Model Number: %s\n", $res->{'gateway'}{'model_no'});
print sprintf("Software Version: %s\n", $res->{'gateway'}{'software_version'});
print sprintf("MAC Address: %s\n", $res->{'gateway'}{'mac_address'});
print sprintf("Uptime: %s\n", $res->{'gateway'}{'uptime'});
# shutdown
my $params = { 'request' => {
'method' => 'system_reboot_save',
'parameters' => {
'action' => 'shutdown',
'confirm' => 'yes'
}
}};
# Change to actually reboot.
if (0) {
print "Shutting down.\n";
$response = $ua->post("https://$GATEWAY_IP/json", {
'request' => JSON->new->utf8->encode($params)
});
} else {
print "NOT ACTUALLY REBOOTING.\n";
}
# Response from reboot/shutdown is unique in that the webserver cannot
# send us a response verifying the shutdown went as expected
# $content = JSON->new->utf8->decode($response->content);
# print Data::Dumper::Dumper($content);
И для любителей Python тоже есть пример:
Отправка email при упавшем линке
import sys
import re
import mechanize
import cookielib
import urllib
import json
from pprint import pprint
def main():
gateway_ip = 'CHANGEME'
gateway_user = 'admin'
gateway_pass = 'admin'
data = {
'admin_uid': gateway_user,
'admin_password': gateway_pass,
'act': 'login'
}
data_str = '&'.join(['%s=%s' % (k,v) for k,v in data.iteritems()])
# Log in
req = mechanize.Request("https://%s/admin/main.html" % gateway_ip, data_str)
cj = cookielib.LWPCookieJar()
cj.add_cookie_header(req)
res = mechanize.urlopen(req)
lines = res.read()
# Response from login is an HTML page. Check that the main page's init()
# function is called to be sure we have logged in and are looking at
# the main page.
if re.search("Welcome,\s+%s" % gateway_user, lines) is None:
print "Login Failed!"
return 1
# Request connection status
data = {
"request" : {
"method": "connection_status.list",
}
}
# Something (mechanize?) doesn't like JSON with spaces in it.
data_str = json.dumps(data, separators=(',',':'))
req = mechanize.Request("https://%s/json" % gateway_ip, data_str)
res = mechanize.urlopen(req)
lines = res.read()
response = json.loads(lines)
result = json.loads(response['response']['result'])
# check result
for interface in result['connection_status']['t1_e1_interfaces']:
if True or interface['status_desc'] != 'Up, Active':
print "%s is down (status '%s') on %s!" % (
interface['name'], interface['status_desc'], gateway_ip
)
# Send an email, postcard, or pidgeon to the sysadmin
sys.exit(main() or 0)
Впрочем получить более подробную информацию Вы можете на wiki.asterisk.org
Варианты использования
Ну в общем, то они не изменились, со времен появления первых представителей G-семейства.
Можно принять E1 потоки от городского провайдера и старой АТС-ки:
Можно использовать данные шлюзы для виртуальных серверов:
Можно использовать для транскодирования:
Или благодаря тому, что количество SIP подключений не ограничено, в первую очередь будет правильно сделать отказоустойчивую маршрутизацию, например с серверами Switchvox:
Расширенная гарантия
Вместе с добавлением новой продукции, производитель решил расширить список доступных услуг. Так, например я уже сейчас могу огласить стоимость расширенной гарантии:
- До 3-ех лет на шлюз Digium G100 — 129$
- До 5-ех лет на шлюз Digium G100 — 216$
- До 3-ех лет на шлюз Digium G200 — 216$
- До 5-ех лет на шлюз Digium G200 — 288$
- До 3-ех лет на шлюз Digium G400 — 324$
- До 5-ех лет на шлюз Digium G400 — 432$
- До 3-ех лет на шлюз Digium G800 — 432$
- До 5-ех лет на шлюз Digium G800 — 576$
Ценовая политика
Цены, рекомендованные производителем следующие:
Digium G100 — 1195$
Digium G200 — 1995$
Digium G400 — 2995$
Digium G800 — 3995$
Разумеется, в рознице России они будут чуточку выше. И в качестве сравнения, Digium приводит следующее сравнение с конкурентами:
Vendor/Model | Digium Gateway Series | Audiocodes Mediant 600 | Audiocodes Mediant 1000/2000 | Mediatrix 3500 Series | NET (formerly Quintum) Tenor | Sangoma Vega Series | Patton SmartNode |
Один E1 | G100 | Mediant 1000 | Model: 3531 | ResponsePoint | Vega 100 | SN4950 | |
* Street Price | 1195 | 2950 | 3300 | 1499 | 1530 | 1158 | 2309 |
* List Price | 1195 | 3278 | 3857 | 1950 | 1800 | 1395 | |
Два Е1 | G200 | Mediant 1000 | Model: 3532 | Tenor DX 2030 | Vega 200 | SN4950 | |
* Street Price | 1995 | 4000 | 4500 | 2299 | 3077 | 1821 | 3999 |
* List Price | 1995 | 4485 | 5277 | 2950 | 3620 | 2195 | |
Четыре Е1 | G400 | Mediant 1000 | Tenor DX 4060 | Vega 400 | |||
* Street Price | 2995 | N/A | 8000 | N/A | 4790 | 7092 | 2050 |
* List Price | 2995 | N/A | 9180 | N/A | 5865 | 8545 | 2700 |
Восемь Е1 | G800 | Mediant 2000 | Tenor DX 8120 | N/A | |||
* Street Price | 3995 | N/A | 15500 | N/A | 9999 | N/A | |
* List Price | 3995 | N/A | 17820 | N/A | 11750 | N/A |
Единственный, кто подошел близко — это Sangoma, но Digium утверждает, что они очень сложны в настройке. Так ли это я сказать не могу, может кто-то сталкивался с этим железом?
В наличии данные продукты ожидаются к сентябрю 2013 г. Спасибо за внимание.
P.S. для тех, кто дошел до конца, даю волшебную ссылочку на доступ к интерфейсу шлюза gatewaytestdrive.digium.com
Можете посмотреть интерфейс, функционал и прочее…