Для удобного конфигурирования и однозначной привязки IP-телефона к сетевому оборудованию, можно использовать механизм Provision, реализованный на подавляющем большинстве IP-телефонов. А благодаря наличию TFTP-сервера и поддержке скриптов на маршрутизаторах Mikrotik, можно настраивать VoIP оборудование исходя из многих факторов.
Задача такова:
На точки выдаётся маршрутизатор Mikrotik и IP-телефон Grandstream. У маршрутизатора есть внутренний учётный номер типа «R32» и телефон должен настраиваться так, чтобы его номер был номер_роутера + префикс. Так как телефоны и роутеры могут перемешиваться между собой, то жёстко вбивать номер нельзя.
Решение:
Скриптом генерируем конфиг для телефона и разрешаем доступ к файлу через TFTP. Скрипт будет выполняться раз в день и чтобы не затереть флеш-память до дыр, необходимо сверить CRC существующего файла и сгенерированного конфига в памяти.
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 |
:global crc8 do={ :local crc 0x0 :local poly 0x7 :local tbl ( "\00", "\01", "\02", "\03", "\04", "\05", "\06", "\07", "\08", "\09", "\0A", "\0B", "\0C", "\0D", "\0E", "\0F", \ "\10", "\11", "\12", "\13", "\14", "\15", "\16", "\17", "\18", "\19", "\1A", "\1B", "\1C", "\1D", "\1E", "\1F", \ "\20", "\21", "\22", "\23", "\24", "\25", "\26", "\27", "\28", "\29", "\2A", "\2B", "\2C", "\2D", "\2E", "\2F", \ "\30", "\31", "\32", "\33", "\34", "\35", "\36", "\37", "\38", "\39", "\3A", "\3B", "\3C", "\3D", "\3E", "\3F", \ "\40", "\41", "\42", "\43", "\44", "\45", "\46", "\47", "\48", "\49", "\4A", "\4B", "\4C", "\4D", "\4E", "\4F", \ "\50", "\51", "\52", "\53", "\54", "\55", "\56", "\57", "\58", "\59", "\5A", "\5B", "\5C", "\5D", "\5E", "\5F", \ "\60", "\61", "\62", "\63", "\64", "\65", "\66", "\67", "\68", "\69", "\6A", "\6B", "\6C", "\6D", "\6E", "\6F", \ "\70", "\71", "\72", "\73", "\74", "\75", "\76", "\77", "\78", "\79", "\7A", "\7B", "\7C", "\7D", "\7E", "\7F" ) for i from=0 to=($2 - 1) do={ :local chr [:pick $1 $i ($i + 1)] set $crc ($crc ^ [:find $tbl $chr]) for j from=0 to=7 do={ if ($crc & 0x80 = 0) do={ set $crc ($crc << 1) } else={ :set $crc ((($crc << 1) & 0xFF) ^ $poly) } } } :local crchex if ($crc & 0xF0 > 0x90) do={:set crchex [:pick $tbl (($crc >> 4) + 0x37)]} else={:set crchex [:pick $tbl (($crc >> 4) + 0x30)]} if ($crc & 0x0F > 9) do={:set crchex ($crchex.[:pick $tbl (($crc & 0xF) + 0x37)])} else={:set crchex ($crchex.[:pick $tbl (($crc & 0xF) + 0x30)])} :return $crchex } :local defaultphone 600 :local filename "cfg.xml.txt" do { :set defaultphone ([:pick [/system identity get name] ([:len [/system identity get name]]-2) [:len [/system identity get name]]]+600) } on-error={:log info "use default phone number 600"} :local cfg ("<\?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" \?>\n\<br /><gs_provision version=\\\"1\\\">\n\<br /><config version=\\\"1\\\">\n\<br /><P271>1</P271>\n\<br /><P270>PHONE\$default_phone</P270>\n\<br /><P47>10.62.5.2</P47>\n\<br /><P35>\$default_phone</P35>\n\<br /><P36>\$default_phone</P36>\n\<br /><P34>Pass\$default_phone\".\"word</P34>\n\<br /><P3>CGB</P3>\n\<br /><P1402>1</P1402>\n\<br /><P1405>0</P1405>\n\<br /><P1377>RSXX0433</P1377>\n\<br /><P1415>0</P1415>\n\<br /><P8>0</P8>\n\<br /><P146>phone-\$default_phone</P146>\n\<br /><P1348>0</P1348>\n\<br /><P2>admin</P2>\n\<br /><P238>0</P238>\n\<br /><P194>2</P194>\n\<br /><P285>1</P285>\n\<br /><P1362>ru</P1362>\n\<br /></config>\n\<br /></gs_provision>\n") :local cfgcrc [$crc8 $cfg [:len $cfg]] if ([:len [/file find name=cfg.xml.txt]] > 0) do={ :local fc [/file get $filename contents] :local filecrc [$crc8 $fc [:len $fc]] if ($cfgcrc = $filecrc) do={ :log info "provision files equals" } else={ /file print file=$filename :delay 2 /file set $filename contents=$cfg } } else={ :log info "provision file not exists. creating" /file print file=$filename :delay 2 /file set $filename contents=$cfg } |
Сначала, скрипт получает строку /system identity, выделяет два последних символа, которые являются номером маршрутизатора и прибавляет к значению телефонного номера по умолчанию (в данном случае — 600). Так как символы могут оказаться не числом, то завернём код в обработчик исключения и при неверной строке просто оставим номер по умолчанию и сообщим об этом в лог.
Далее, создаём строку с конфигурацией, в которую вставляем из переменной полученный номер телефона и считаем её CRC8. Если файл существует в файловой системе, то считаем его контрольную сумму и сравниваем с CRC конфигурации в памяти и если контрольные суммы равны, значит ничего не изменилось и можно оставить всё как есть, иначе перезаписываем файл.
Теперь разрешаем доступ к файлу через TFTP, добавив в конфигурацию Mikrotik следующие строки:
1 |
/ip tftp add real-filename=cfg.xml.txt req-filename=cfg.xml |
И не забудем добавить скрипт в планировщик:
1 |
/system scheduler add interval=1d name=phone on-event=phone policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=jan/01/1970 start-time=00:00:00 |