Около года назад мне пришлось столкнуться с новой для себя задачей – автоматизацией управления.
АТС .
На первый взгляд в этом нет ничего сложного: нужно подключиться к управляющему порту АТС через TCP или Serial интерфейс, отправить команду и проанализировать ответ. Как выяснилось в ходе работы, эта простота оказалась обманчивой.
В своей статье я хочу рассказать о трудностях, с которыми мне пришлось столкнуться в процессе работы.
Вряд ли эта статья будет интересна широкому кругу читателей, но, возможно, специалисты телефонии найдут в ней что-то полезное.
В качестве иллюстративного материала я буду использовать примеры команд АТС.
Алкатель С12 И М200 в настоящее время поддерживается проектом.
1. Глоссарий Для начала следует определиться с терминологией.
1.1 Задачи
Упражнение представляет собой набор действий, выполняемых атомарно.С точки зрения подсистемы управления оборудованием задача состоит из набора услуги .
Каждая услуга контролирует доступ абонента к определенной услуге (например, можно выбрать услуги доступа к междугородной и международной связи).
При выполнении задачи отдельные сервисы можно включать или отключать.
Кроме того, для ряда сервисов могут быть установлены значения конфигурации параметры (например, время будильника или значение PIN-кода).
В качестве параметров также рассматриваются логические значения, определяющие состояние подключения или отключения конкретной службы.
С аппаратной точки зрения процесс подключения или отключения какой-либо службы сводится к выполнению одного или нескольких команды .
Назовем процесс выполнения команд на оборудовании активация .
1.2 Технические характеристики
Технические характеристики руководить работой специализированных ОРМ , предназначенный для интеграции приложения с подсистемой Управление заказами , который контролирует выполнение задач.Я не буду углубляться в эту тему, поскольку она не связана с конкретными вопросами взаимодействия с АТС.
Чтобы понять дальнейшее обсуждение, достаточно знать, что этот уровень обеспечивает доступ для чтения и записи к именованным объектам.
переменные , содержащий значения, загруженные из базы данных.
Помимо доступа к скалярным значениям предоставляется доступ к коллекциям кортежей.
Так, например, открыв коллекцию, представленную именем 'tk' (Техническая карта), можно получить доступ к записям, содержащим данные технической карты, например 'tk.phone' - номер телефона абонента или 'tk.ats_type' - тип АТС.
.
В свою очередь, эти записи могут содержать ссылки на другие коллекции.
Вложенность коллекций не ограничена.
Из всего сказанного выше может быть не очень понятно, почему используется термин спецификация? Дело в том, что при разработке этого слоя активно использовались следующие концепции SID вроде Спецификации и Политики, которые, с моей точки зрения, значительно упростили разработку.
В общем, настоятельно рекомендую ознакомиться с материалами ТМ Форум - и всем, у кого есть такая возможность.
1.3 Скрипты
Я уже описал эту подсистему ранее .Изначально скрипт выполнял две задачи: описывал порядок выполнения команд внутри рабочего задания и скрывал платформенно-зависимые особенности.
Скрипт обращался к переменным, предусмотренным спецификациями, и генерировал команды в зависимости от типа АТС.
Вот как это выглядело: Фрагмент сценария первой версии
Из приведенного выше фрагмента видно, что анализируя переменную tk.attach.service, мы определяем, какую команду следует выполнить..
[002082] platform:M-200; if (tk.attach.service = 'SET_HOLD') { [020820] < text:settune %s enb_flash=on; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; [020821] is_rollback:1; { [001020] < device_id:tk.ats_id; [020822] < text:settune %s enb_flash=off; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; } } [003082] platform:S-12; if (tk.attach.service = 'SET_HOLD') { [030820] < text:MODIFY-SUBSCR:DN=K'%s,RECALL=ADD&ECTRF.; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; [030821] is_rollback:1; { [001020] < device_id:tk.ats_id; [030822] < text:MODIFY-SUBSCR:DN=K'%s,RECALL=REMOVE&ECTRF.; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; } } .
Затем, в зависимости от платформы, путем подстановки номера телефона из переменной tk.phone в соответствующий шаблон команды генерируется команда для выполнения на оборудовании.
Так как различных команд было довольно много, скрипт получился большим (более 1000 строк) и сложным для понимания.
В результате при разработке второй версии было решено отказаться от формирования отдельных команд в скрипте (переведя его на более низкий уровень), передавая на исполнение служебные коды вместо готовых команд. Это решение очень благотворно сказалось на размере сценария.
Вот как выглядит весь скрипт второй версии: Скрипт второй версии [002000] {
[200001] var_list:retry_cnt = retry_cnt + 1, state = 1;
[200002] if (subtype = -1) {
[200003] foreach (devices) {
[200004] < device_id:devices.ats_id; device_ip:devices.ats_ip; device_password:devices.ats_password; device_port:devices.ats_tcp_port; device_protocol:devices.ats_type;
[200005] < device_id:devices.ats_id;
[200006] < text:ROLLBACK;
[200007] var_list:retry_cnt = 0;
}
}
[200008] if (subtype = 1) {
[200009] foreach (tk) {
[200010] if (tk.phone = '') {
[200011] var_list:tk.phone = tk.phone_old;
}
[200012] < device_id:tk.ats_id; device_protocol:tk.ats_type; device_ip:tk.ats_ip; device_port:tk.ats_tcp_port; device_password:tk.ats_password;
[200013] var_list:action = 0, is_dou_activated = 0;
[200014] target:tk.ats_type; foreach (tk.detach) {
[200015] < device_id:tk.ats_id;
[200016] var_list:activate_command = 1;
[200017] platform:S-12; if (tk.detach.service = 'C_INTRAAREAL' | tk.detach.service = 'C_INTERCITY' | tk.detach.service = 'C_INTERNATIONAL') {
[200018] if (is_dou_activated = 1) {
[200019] var_list:activate_command = 0;
}
[200020] var_list:is_dou_activated = 1;
}
[200025] if (activate_command = 1) {
[200026] < text:%s; var_list:tk.detach.service;
[200027] var_list:retry_cnt = 0;
}
}
[200028] var_list:action = 1, is_dou_activated = 0, is_cat_activated = 0;
[200029] target:tk.ats_type; foreach (tk.attach) {
[200030] < device_id:tk.ats_id;
[200031] var_list:activate_command = 1;
[200032] platform:S-12; if (tk.attach.service = 'C_INTRAAREAL' | tk.attach.service = 'C_INTERCITY' | tk.attach.service = 'C_INTERNATIONAL') {
[200033] if (is_dou_activated = 1) {
[200034] var_list:activate_command = 0;
}
[200035] var_list:is_dou_activated = 1;
}
[200021] if (tk.attach.service = 'CATEG_AON_0' | tk.attach.service = 'CATEG_AON_1' | tk.attach.service = 'CATEG_AON_2' | tk.attach.service = 'CATEG_AON_3' | tk.attach.service = 'CATEG_AON_4' | tk.attach.service = 'CATEG_AON_6' | tk.attach.service = 'CATEG_AON_7' | & tk.attach.service = 'CATEG_AON_8' | tk.attach.service = 'CATEG_AON_9') {
[200022] if (is_cat_activated = 1) {
[200023] var_list:activate_command = 0;
}
[200024] var_list:is_cat_activated = 1;
}
[200036] if (activate_command = 1) {
[200037] < text:%s; var_list:tk.attach.service;
[200038] var_list:retry_cnt = 0;
}
}
}
}
}
Логику его выполнения я объясню в последующих разделах, а пока скажу только, что теперь скрипт исключительно управляет последовательностью подключения и отключения сервисов внутри задачи.
Мы по-прежнему можем выполнять разный код в зависимости от типа используемого оборудования, но теперь это используется только тогда, когда зависимость от платформы имеет значение для всей работы, а не для отдельных команд.
1.4 Адаптер
Адаптер это подключаемый модуль ( плагин ), реализующий логику работы с конкретным типом оборудования.В первой версии адаптер получал готовые команды из скрипта и его роль ограничивалась передачей этих команд на АТС по TCP или Serial-соединению и обработкой полученного ответа.
В текущей (второй) версии логика формирования набора команд при подключении или отключении того или иного сервиса перенесена в адаптер.
Объяснению причин, по которым это было сделано, посвящена данная статья.
1.5 Синхронизация
Синхронизация назовем процесс получения текущих настроек абонентов с оборудования.Принципиальной для данного класса задач является проблема несоответствия данных о состоянии настроек абонентов на АТС относительно базы данных.
Эта проблема актуальна не только для телефонии.
В предыдущем проекте активации, связанном с управлением оборудованием омуль он стоял не менее резко.
Можно сказать, что в этой статье рассказывается о том, как сделать процесс активации более «умным» с помощью синхронизации.
2. Уровень задачи
Очевидно, что для управления разными типами АТС используются совершенно разные системы команд, например, для отключения исходящей связи в АТС М-200 используется команда: settune XXXXXXX cmn_outcome=off
и в Alcatel S12: MODIFY-SUBSCR:DN=K'XXXXXXX,OCB=REMOVE&TOTALBAR.
Но подобные различия в синтаксисе команд — далеко не единственная трудность.
Давайте рассмотрим этот вопрос более подробно.
2.1 Сопоставление сервисов с командами
Первое, с чем мы сталкиваемся, это то, что возможности по активации различных услуг, предоставляемые разными АТС, также различны.Конечно, существует некий общий набор сервисов, поддерживаемых большинством типов АТС, таких как контроль исходящих вызовов, настройка будильника, контроль автодозвона и т.д. При этом значительная часть команд, интересных с точки зрения бизнеса, может быть не реализована на том или ином типе АТС (и чем больше набор поддерживаемых типов АТС, тем больше таких команд будет).
быть).
Это означает, что услуга, включенная в задачу, не всегда может быть выполнена на той АТС, где производится активация.
Попытка активировать такую услугу может быть расценена как ошибка, а может быть просто проигнорирована.
Важно, чтобы был реализован механизм отображения используемых сервисов в составе задач для сервисов, реализованных на поддерживаемых типах АТС.
Одна служба заданий может быть сопоставлена с несколькими различными поддерживаемыми службами УАТС.
Например, М-200 поддерживает следующие команды для включения PIN-кода: settune XXXXXXX dvo_pincode=on
settune XXXXXXX dvo_pincodetwo=on
Первый предполагает использование ПИН-кода для междугородных и международных звонков, второй — для всех исходящих звонков.
В нашем случае одним из требований Заказчика было то, чтобы обе эти услуги на уровне задания были отображены в одну общую услугу «ПИНКОД».
Точная услуга, которая будет выполняться, определяется значением дополнительных переменных.
Для Alcatel S12 реализована только одна команда включения ПИН-кода: MODIFY-SUBSCR:DN=K'XXXXXXX,PASSWORD=ADD&"YYYY",SUBCTRL=ADD&OCBVAR.
Помимо того, что разделения данной услуги на два типа нет, можно заметить, что данная команда не только разрешает использование ПИН-кода, но и устанавливает его значение.
Разумеется, М-200 позволяет выполнить, например, следующую команду: settune XXXXXXX dvo_pincode=on pincode=YYYY
Но в процессе внедрения в коммерческую эксплуатацию первой версии модуля активации выяснилось, что эти команды удобнее активировать отдельно.
Кроме того, оказалось, что для того, чтобы ПИН-код сработал, необходимо активировать еще одну команду.
Таким образом, для М-200 команда Set PIN должна активировать три команды в указанном порядке: settune XXXXXXX enb_pincode=on
settune XXXXXXX dvo_pincode=on
settune XXXXXXX pincode=YYYY
Более того, команду enb_pincode, контролирующую возможность использования PIN-кода, можно выполнить отдельно (добавив таким образом еще один вариант отображения сервиса PINCODE).
В этом случае ПИН-код может установить сам абонент. Это приводит к довольно нетривиальной проблеме, о которой я расскажу ниже, в разделе «Проблемы, связанные с синхронизацией».
2.2 Ограничение исходящей связи
АТС разных типов могут отличаться не только набором поддерживаемых сервисов, но и способом реализации этих сервисов.
Так для М-200 доступ к внутризоновой, междугородной и международной связи можно контролировать отдельно: settune XXXXXXX cmn_82xxx=on
settune XXXXXXX cmn_8xxx=on
settune XXXXXXX cmn_10xxx=on
Для Alcatel S12 аналогичные команды выглядят так: MODIFY-SUBSCR:DN=K'XXXXXXX,OCB=MODIFY&PERM&5.
MODIFY-SUBSCR:DN=K'XXXXXXX,OCB=MODIFY&PERM&4.
MODIFY-SUBSCR:DN=K'XXXXXXX,OCB=REMOVE.
Вы можете заметить, что эти команды контролируют состояние всего одной настройки (при включенной междугородной связи ограничения просто снимаются).
Это приводит к следующей проблеме:
- Для М-200 услуги включения внутризоновой, междугородной и международной связи необходимо активировать самостоятельно (и сопоставить один-к-одному с соответствующими сервисами задач)
- При активации на Alcatel S12 должна быть активирована только одна из включенных услуг, та, которая меньше всего ограничивает доступ.
Если в дальнейшем будет подана команда на включение внутризоновой связи, междугородная связь для абонента будет отключена! Одновременная активация внутризоновой и международной связи при отключенной междугородной связи невозможна (в отличие от М-200).
Это хороший пример функциональности, реализованной на уровне сценария активации.
Давайте посмотрим, как это можно реализовать: [200028] var_list:action = 1, is_dou_activated = 0, is_cat_activated = 0;
[200029] target:tk.ats_type; foreach (tk.attach) {
[200031] var_list:activate_command = 1;
[200032] platform:S-12; if (tk.attach.service = 'C_INTRAAREAL' |
tk.attach.service = 'C_INTERCITY' |
tk.attach.service = 'C_INTERNATIONAL') {
[200033] if (is_dou_activated = 1) {
[200034] var_list:activate_command = 0;
}
[200035] var_list:is_dou_activated = 1;
}
[200036] if (activate_command = 1) {
[200037] < text:%s; var_list:tk.attach.service;
[200038] var_list:retry_cnt = 0;
}
}
Переменные нас спасают. Активировав первую команду, управляющую исходящей связью в коллекции tk.attach, мы устанавливаем флаг is_dou_activated, который отключает активацию последующих команд. Причем этот код работает только для Alcatel S12.
Единственное, что нам нужно, чтобы этот подход работал, это чтобы команды шли в правильном порядке: сначала включить международную связь (если она есть), затем междугородную и внутризоновую.
К счастью, спецификации позволяют сортировать выбор.
коллекции по любому критерию.
Вам нужно только добавить поля приоритета в таблицу услуг при подключении и отключении.
3. Проблемы связанные с синхронизацией Как я уже говорил выше, возможность получения текущих настроек от оборудования является одним из основных требований для выполнения хоть какой-то корректной активации.
Давайте разберемся, почему это так?
3.1 Умная активация
Самое первое дополнительное требование, которое мы получили от Заказчика при внедрении первой версии продукта, заключалось в том, что ранее активированные на оборудовании настройки не должны быть повторно активированы.Это действительно важно по двум причинам:
- Активация команд на оборудовании – процесс не быстрый.
Среднее время выполнения одной команды на Alcatel S12 составляет ~10 секунд (M-200 гораздо быстрее (~1 секунда), поскольку возвращает гораздо меньший объем данных).
Добавим к этому, что соединение с АТС очень нестабильное и потерять его мы можем в течение этих самых 10 секунд. Если каждый раз при повторном выполнении задачи (а мы должны выполнять все команды, составляющие задачу, чтобы обеспечить атомарность ее выполнения) мы повторно активируем все команды с самого начала, то, в худшем случае, мы активируйте эти команды снова и снова и никогда не дойдете до конца задачи
- В некоторых случаях (на Alcatel S12) повторная активация команды может привести к ошибке.
В этом случае мы не можем увидеть состояние настроек в базе данных, так как возможно активация для данного абонента проводится впервые.
В этом случае единственным правильным решением будет получение состояния настроек непосредственно от оборудования, до выполнения команды активации.
В случае, если настройки уже находятся в требуемом состоянии, мы можем отказаться от выполнения сработавшей команды и двигаться дальше (если сработавшая команда не может быть выполнена из-за конфликта настроек, мы также можем не выполнять команду и сразу вызвать исключение ).
Этот подход отлично работает для М-200, потому что:
- Все настройки подписчика возвращаются в ответ всего на одну команду gettune.
- Активация на М-200 происходит относительно быстро, соединение стабильное.
Мы можем позволить себе запускать одну дополнительную команду в начале каждой активации.
Для чтения настроек вам придется выполнять различные команды и все они будут выполняться медленно.
Таким образом, невозможно обойтись без сохранения состояния настроек в базе данных.
При выполнении активации мы сможем получить значения настроек из базы данных и, только если их там нет, сгенерировать необходимые команды для получения недостающих значений от оборудования.
Конечно, это не идеальное решение, так как при ручном выполнении команд в обход подсистемы активации данные в базе будут рассинхронизированы, но это меньшее из зол, которое мы можем себе позволить.
Кроме того, по завершении активации команды нам станут известны текущие значения настроек (поскольку команда их успешно изменила) и мы сможем обновить рассинхронизированные данные в базе данных.
Также есть проблема при использовании М-200. В некоторых случаях настраивать -сервер, используемый для взаимодействия с АТС, о котором я расскажу ниже, начинает работать некорректно.
На все команды настройки отвечает Ок, хотя данные на АТС не меняются! Вызов gettune в этом случае приводит к ошибке.
Это означает, что для М-200 мы должны вызывать gettune не только до, но и после активации и в случае получения ошибки мы должны инициировать повторное выполнение задания.
Как только сервер настройки начнет работать корректно, мы сможем активировать те команды, которые фактически не были активированы при выполнении предыдущего задания.
То, что было успешно активировано, больше не будет активировано.
3.2 Зависимые услуги
Как я уже описывал выше, на АТС М-200 включение услуги «ПИНКОД» (в зависимости от значений переменных спецификации) может привести к активации одной из трёх последовательностей команд: settune XXXXXXX enb_pincode=on
settune XXXXXXX enb_pincode=on
settune XXXXXXX dvo_pincode=on
settune XXXXXXX pincode=YYYY
settune XXXXXXX enb_pincode=on
settune XXXXXXX dvo_pincodetwo=on
settune XXXXXXX pincode=YYYY
Параметр enb_pincode включен во всех трех случаях.
Легко представить возможную ошибку, возникающую при наивной реализации активации этих команд:
- Услуга активирована, включая настройку enb_pincode, которая позволяет абоненту самостоятельно установить ПИН-код.
- Активируется услуга, устанавливающая ПИН-код для исходящей связи (в рамках которой повторно активируется enb_pincode)
- Абонент отказывается от услуги enb_pincode
Мы должны записывать все активированные службы в базу данных и проводить дополнительные проверки при активации команд выключения.
Если отключаемая настройка все еще используется какой-либо другой службой, которая не была отключена, команда отключения должна игнорироваться.
Да, абонент сможет пользоваться услугой enb_pincode, от которой он фактически отказался, но установленные ПИН-коды будут работать без каких-либо претензий со стороны абонента.
Таких зависимостей в системе команд М200 не очень много, но все они связаны с важными сервисами (такими как установка будильника или включение переадресации вызовов).
Учет этих зависимостей важен с точки зрения корректной активации.
3.3 Реализация отката
Не каждое задание можно выполнить успешно.Активация команды может не удаться из-за неправильных данных (абонентский номер не обслуживается данной АТС, неправильное время при установке будильника и т.п.
), либо из-за конфликта активированных услуг (такое случается довольно часто на Alcatel С12).
Такие ошибки мы будем называть неисправимыми.
Поскольку задача должна выполняться атомарно, в случае возникновения неисправимой ошибки нам придется «откатить» все команды, которые были успешно активированы ранее в рамках той же задачи.
Первое, что приходит на ум — запомнить все команды, которые были успешно выполнены, и в случае возникновения ошибки выполнить обратные команды.
Реализацию этого подхода можно увидеть в старой версии скрипта: .
[002391] platform:M-200; if (tk.detach.service = 'PINCODE' & tk.detach.act_mode = 0 & tk.detach.act_level = 2) { [023910] < text:settune %s dvo_pincode=off; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; [001610] < text:settune %s pincode=; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; [022010] < text:settune %s enb_pincode=off; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; [023911] is_rollback:1; if (tk.detach.value != '') { [001020] < device_id:tk.ats_id; [023912] < text:settune %s dvo_pincode=on; var_list:tk.phone; [001041] > is_error:1; regexp:(.
+); var_list:error; [001603] < text:settune %s pincode=%s; var_list:tk.phone, tk.detach.value; [001041] > is_error:1; regexp:(.
+); var_list:error; } } .
Здесь сразу после успешного отключения службы «PINCODE» обратные команды для включения службы сохраняются в стеке команд отмены.
Помимо чрезмерной многословности, этот подход имеет ряд других недостатков.
- Корректная реализация этого подхода очень трудоемка.
Дело в том, что для выполнения обратных команд необходимы значения переменных на момент активации прямой команды, но часть этих переменных находится в коллекциях, просматриваемых оператором foreach. Это значит, что при формировании команды реверса требуется сохранять «снимки» состояния этих коллекций (и вложенных в них подколлекций) и при откате использовать именно их, а не исходные спецификации.
Кроме того, такие команды, как сброс PIN-кода, требуют, чтобы обратная команда имела значение PIN-кода для его сброса, и мы должны добавить это значение в спецификацию, даже если команда вперед его не использует.
- Выполнение команд отката после возникновения ошибки активации может привести к ошибке на Alcatel S12. Например, если какой-либо из параметров задан неверно, АТС запрашивает правильное значение и ожидает его получения, а не команды отката.
Прием команды в этом контексте приводит к ошибке, в результате которой команда отката не выполняется.
В разделе «Проверка параметров» я рассмотрю этот вопрос более подробно.
- Этот подход не работает! На самом деле нам неоткуда взять правильные значения параметров не только для команды установки ПИН-кода, но и для команд включения enb_pincode и dvo_pincode. Если мы отключили их при выполнении задачи, это не значит, что они еще не были отключены до активации задачи.
В этом случае включение этих настроек в процессе отката будет ошибкой.
Чтобы закрыть этот вопрос, остается упомянуть еще об одном моменте.
Дело в том, что задача активации может активировать команды на нескольких АТС (например, при переводе абонента с одной АТС на другую).
Настройки доступа к АТС хранятся в коллекции tk, и может оказаться так, что после успешного выполнения команды на одной АТС мы получили ошибку при выполнении команды на другой.
В открытой записи коллекции тк в этот момент уже нет параметров доступа к АТС, на которой следует выполнить откат. Самый простой способ справиться с этой проблемой — после инициирования отката вызвать активацию задачи для перезапуска.
В этом случае все коллекции будут открыты заново и будет выполнена услуга «ОТКАТ» для всех АТС, участвующих в активации: .
[200002] if (subtype = -1) { [200003] foreach (tk) { [200015] < device_id:tk.ats_id; [200006] < text:ROLLBACK; .
} } .
3.4 Активация возобновляемых источников энергии
Помимо неисправимых ошибок, рассмотренных в предыдущем разделе, возможны ошибки, после которых активацию можно продолжить.Например, если в процессе активации TCP-соединение с АТС было закрыто, откат не требуется.
В этом случае достаточно повторить активацию, пропуская выполнение ранее активированных команд. Вот как выглядит иерархия исключений, выдаваемых при активации:
Исключения, подразумевающие необходимость возобновления активации, наследуются от RetryRequiredException. RollbackRequiredException дополнительно запускает откат активации.
Незапланированные ошибки выдаются RuntimeAeException, прекращая работу службы активации с соответствующей диагностикой.
Возобновление активации из-за потери соединения с АТС (TcpConnectionLostException) может произойти в двух принципиально разных случаях:
- Потеря соединения с АТС во время активации
- Невозможность подключиться к АТС в первый раз
Поскольку АТС в принципе доступна, повторив активацию несколько раз (с задержкой в несколько минут), рано или поздно мы выполним задачу.
Во втором случае ошибка, например, может быть вызвана тем, что неправильно установлены параметры доступа к АТС.
В этом случае необходимо сделать несколько попыток подключения, после чего должно быть выдано сообщение об ошибке.
Эта логика реализуется скриптом: [002000] {
[200001] var_list:retry_cnt = retry_cnt + 1, state = 1;
.
[200008] if (subtype = 1) { [200009] foreach (tk) { .
[200014] target:tk.ats_type; foreach (tk.detach) { [200015] < device_id:tk.ats_id; .
[200025] if (activate_command = 1) { [200026] < text:%s; var_list:tk.detach.service; [200027] var_list:retry_cnt = 0; } } .
}
В самом начале скрипта мы увеличиваем счетчик попыток (если переменная не определена спецификацией, она автоматически создается с нулевым значением), а после успешного выполнения любой команды сбрасываем его в 0. Если значение счетчика превышает максимальное количество попыток подключения, это отслеживается спецификацией и генерирует исключение с соответствующей диагностикой.
4. Проверка параметров Важным моментом является необходимость валидации значений параметров, подставляемых в команды.
Как я уже говорил выше, передача неверного значения в параметр может сделать невозможным автоматическое выполнение последующих команд (например, команд отката): 10.0.5.130:4001> MODIFY-SUBSCR:DN=K'8553377684,ALMCALL=ACTIVATE&06&00&00.
10.0.5.130:4001> SEQ=1306.130403 9002
10.0.5.130:4001> COM=4294
10.0.5.130:4001> JOB SUBMITTED
10.0.5.130:4001>
10.0.5.130:4001>
10.0.5.130:4001> ARGUMENT SEMANTIC ERROR : ALMCALL ARG 0004
10.0.5.130:4001> ERROR CODE = 0008
10.0.5.130:4001> <
10.0.5.130:4001< MODIFY-SUBSCR:DN=K'8553377684,ALMCALL=ACTIVATE&06&00&00.
10.0.5.130:4001> MODIFY-SUBSCR:DN=K'8553377684,SUBCTRL=REMOVE&CWTG.
10.0.5.130:4001> PARAMETER NOT EXISTENT ; MODIFY-S
10.0.5.130:4001> <
Конечно, можно анализировать закономерности таких ошибок и автоматически генерировать дополнительные команды, переводящие АТС в состояние ожидания следующей команды, но это существенно усложнит алгоритм взаимодействия с АТС.
Гораздо проще избежать подобных ошибок.
Это довольно легко сделать.
Например, чтобы проверить значение количества срабатываний сигнализации, нулевое значение Теги: #АТС #Alcatel S12 #m200 #Разработка сайтов #Разработка систем связи
-
Мир Неполный Без Мобильных Приложений
19 Oct, 24 -
Бесплатная Косметика. Пока Еще В Наличии
19 Oct, 24