Введение
В этой статье описаны примеры использования JSON-RPC API для удалённого управления роутерами TELEOFIS LT40 и LT5x на примере изменения APN и чтения состояния устройства. Для выполнения команд используется Windows PowerShell.
Интерфейс JSON-RPC позволяет читать и изменять любые параметры конфигурации UCI, а также выполнять команды на устройстве - то есть делать через HTTP всё то же, что и через веб-интерфейс или SSH. Это удобно для массового обслуживания парка роутеров: смены APN, сбора статистики, перезагрузки по расписанию из внешней системы.
Примеры проверены на роутере LT50 с прошивкой va1.2.2. Модуль luci-mod-rpc, обеспечивающий работу JSON-RPC, входит в состав прошивки начиная с версии vaX.2.2. Текущую версию можно посмотреть в меню Состояние → Система.
С дополнительной информацией по использованию JSON-RPC API можно ознакомиться здесь:
HowTo: Using the JSON-RPC API
Managing OpenWrt remotely with cURL
Обратите внимание: при обращении по http:// логин и пароль передаются в открытом виде. При управлении роутером через сети общего пользования используйте HTTPS или организуйте доступ через VPN-туннель.
Получение токена аутентификации
Первым шагом является аутентификация и получение токена, который будет использоваться в последующих запросах.
В атрибуте "params" необходимо указать логин/пароль для авторизации в устройстве. По умолчанию - root/root.
В атрибуте -Uri следует указать локальный IP-адрес роутера. По умолчанию - 192.168.88.1.
$ip = "192.168.88.1"
$body = @{ id = 1; method = "login"; params = @("root", "root") } | ConvertTo-Json
$authResponse = Invoke-RestMethod -Uri "http://$ip/cgi-bin/luci/rpc/auth" -Method Post -Body $body -ContentType "application/json"
$authToken = $authResponse.result
Write-Host "Token: $authToken"
В ответ на запрос будет возвращён 32-символьный токен, который потребуется передавать во всех последующих запросах в параметре auth:
Token: 4acd9ec150dd1dd8a7a823d82051bcbf
Если поле Token пустое - проверьте логин и пароль. Если запрос завершается ошибкой 404 - на устройстве не установлен модуль luci-mod-rpc, обновите прошивку.
Далее в примерах используются два адреса:
/cgi-bin/luci/rpc/uci- работа с конфигурацией UCI (методыget,get_all,set,commit);/cgi-bin/luci/rpc/sys- выполнение команд на устройстве (методexec).
$uciUri = "http://$ip/cgi-bin/luci/rpc/uci?auth=$authToken" $sysUri = "http://$ip/cgi-bin/luci/rpc/sys?auth=$authToken"
Изменение APN
Прежде чем менять параметры, полезно просмотреть текущую конфигурацию целиком. Метод get_all возвращает содержимое указанного конфига:
$body = @{ id = 1; method = "get_all"; params = @("network") } | ConvertTo-Json
$response = Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType "application/json"
$response | ConvertTo-Json -Depth 6
В роутерах LT40 и LT5x имя точки доступа задаётся в конфигурации службы Менеджер SIM - отдельно для каждой SIM-карты:
simman.@sim0[0].GPRS_apn- APN первой SIM-карты;simman.@sim1[0].GPRS_apn- APN второй SIM-карты.
Секции SIM-карт в конфиге simman являются анонимными: их имена (cfg02ebfe, cfg03ebff и подобные) генерируются автоматически и на каждом устройстве свои. Поэтому обращаться к ним следует по типу секции с указанием индекса - @sim0[0] для первой SIM-карты и @sim1[0] для второй. Такой синтаксис корректно работает и в методе get, и в методе set.
Чтение текущего значения:
$body = @{ id = 1; method = "get"; params = @("simman", "@sim0[0]", "GPRS_apn") } | ConvertTo-Json
$response = Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType "application/json"
Write-Host "APN SIM1: $($response.result)"
Запись нового значения APN (в примере - internet2):
$params = @(
@("simman", "@sim0[0]", "GPRS_apn", "internet2"),
@("simman", "@sim1[0]", "GPRS_apn", "internet2")
)
foreach ($p in $params) {
$body = @{ id = 1; method = "set"; params = $p } | ConvertTo-Json
$response = Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType "application/json"
Write-Host "set $($p[0]).$($p[1]).$($p[2]) -> $($response.result)"
}
В ответ на каждый успешный запрос сервер возвращает true. Если параметр result отсутствует или равен false, значит в запросе есть ошибка либо истёк срок жизни токена.
Применение настроек
Метод set записывает изменения только в промежуточный буфер UCI. Чтобы сохранить их в конфигурационный файл, необходимо выполнить commit:
$body = @{ id = 1; method = "commit"; params = @("simman") } | ConvertTo-Json
$response = Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType "application/json"
Write-Host "commit simman -> $($response.result)"
После commit настройки записаны на диск, но работающая служба продолжает использовать старые значения. Применить их без полной перезагрузки роутера можно, перезапустив Менеджер SIM через метод exec:
$body = @{ id = 1; method = "exec"; params = @("/etc/init.d/simman restart") } | ConvertTo-Json -Compress
$response = Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType "application/json"
Write-Host $response.result
При перезапуске служба заново поднимет сотовое соединение и подставит APN активной SIM-карты в параметр network.internet.apn. Убедиться, что значение применилось, можно как через веб-интерфейс, так и запросом:
$body = @{ id = 1; method = "exec"; params = @("uci get simman.@sim0[0].GPRS_apn; uci get network.internet.apn") } | ConvertTo-Json -Compress
(Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType "application/json").result
Веб-интерфейс до изменения APN:
И после:
Если требуется полная перезагрузка устройства, её также можно выполнить удалённо:
$body = @{ id = 1; method = "exec"; params = @("reboot") } | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType "application/json"
Чтение состояния устройства
Для получения сводной информации о состоянии модема, SIM-карт и питания используется команда ubus call info info:
$body = @{ id = 1; method = "exec"; params = @("ubus call info info") } | ConvertTo-Json -Compress
$response = Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType "application/json"
Write-Host $response.result
Пример ответа:
{
"serialnum": "860147059202109",
"voltage": "23.678",
"temperature": "46 °C",
"netname": "MegaFon (25002)",
"nettype": "lte",
"rssi": "-69 dBm",
"rsrp": "-101 dBm",
"rsrq": "-14 dB",
"snr": "7 dB",
"ccid": "897010262732497899",
"imsi": "250026273249789",
"sim_state": "1 INSERTED (ACT) | 2 NOT INSERTED"
}
Назначение полей:
serialnum- серийный номер устройства (IMEI модема);voltage- входное напряжение питания, В;temperature- температура процессора;netname,nettype- оператор и тип сети регистрации;rssi,rsrp,rsrq,snr- параметры уровня и качества сигнала;ccid,imsi- идентификаторы активной SIM-карты;sim_state- состояние обоих SIM-слотов; метка(ACT)указывает на активный слот.
Метод exec позволяет выполнить любую команду интерпретатора, поэтому таким же образом можно, например, просмотреть все параметры, связанные с SIM-картами:
$body = @{ id = 1; method = "exec"; params = @("uci show simman") } | ConvertTo-Json -Compress
(Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType "application/json").result
Полный пример скрипта
Ниже приведён законченный сценарий: аутентификация, чтение текущего APN, запись нового значения, применение и проверка результата.
$ip = "192.168.88.1"
$newApn = "internet2"
# Аутентификация
$body = @{ id = 1; method = "login"; params = @("root", "root") } | ConvertTo-Json
$authToken = (Invoke-RestMethod -Uri "http://$ip/cgi-bin/luci/rpc/auth" -Method Post -Body $body -ContentType "application/json").result
if (-not $authToken) { Write-Host "Ошибка аутентификации"; return }
$uciUri = "http://$ip/cgi-bin/luci/rpc/uci?auth=$authToken"
$sysUri = "http://$ip/cgi-bin/luci/rpc/sys?auth=$authToken"
# Текущее значение
$body = @{ id = 1; method = "get"; params = @("simman", "@sim0[0]", "GPRS_apn") } | ConvertTo-Json
Write-Host "Текущий APN: $((Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType 'application/json').result)"
# Запись нового значения
$params = @(
@("simman", "@sim0[0]", "GPRS_apn", $newApn),
@("simman", "@sim1[0]", "GPRS_apn", $newApn)
)
foreach ($p in $params) {
$body = @{ id = 1; method = "set"; params = $p } | ConvertTo-Json
Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType "application/json" | Out-Null
}
# Сохранение и применение
$body = @{ id = 1; method = "commit"; params = @("simman") } | ConvertTo-Json
Invoke-RestMethod -Uri $uciUri -Method Post -Body $body -ContentType "application/json" | Out-Null
$body = @{ id = 1; method = "exec"; params = @("/etc/init.d/simman restart") } | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType "application/json" | Out-Null
# Проверка
$body = @{ id = 1; method = "exec"; params = @("uci get simman.@sim0[0].GPRS_apn") } | ConvertTo-Json -Compress
Write-Host "Новый APN: $((Invoke-RestMethod -Uri $sysUri -Method Post -Body $body -ContentType 'application/json').result)"
Заключение
JSON-RPC API роутеров LT40 и LT5x даёт полный программный доступ к конфигурации устройства: методы get, set и commit работают с любыми параметрами UCI, а метод exec позволяет выполнять команды и получать данные о состоянии модема и питания. На основе приведённых примеров можно построить сценарии массового обслуживания парка роутеров - от смены APN при переходе на другого оператора до периодического сбора телеметрии.
При работе с API учитывайте два момента: изменения, внесённые методом set, вступают в силу только после commit и перезапуска соответствующих служб, а обращение по http:// передаёт учётные данные в открытом виде и допустимо только в доверенной сети.