Intelligent Security Systems Интеграция внешних модулей с системой Inspector+ 25. 11. 2002




Скачать 167.43 Kb.
Дата16.06.2016
Размер167.43 Kb.

Intelligent Security Systems ©

Интеграция внешних модулей с системой Inspector+

25.11.2002
Процесс интеграции внешних модулей с системой Inspector+ состоит из следующих этапов:

  • Внесение необходимых изменений в файл “niss.dbi”;

  • Внесение необходимых изменений в файл “niss_eng.ddi” или “niss_rus.ddi” (в зависимости от версии системы Inspector+);

  • Предварительная подготовка DLL-файла с именем “niss_module.dll” и добавление его в корневой каталог Inspector’a;

  • Предварительная подготовка исполнительного модуля с именем “module.exe” и добавление его в корневой каталог Inspector’a;

Все это подробно описаны ниже. Введем заранее во избежание недоразумений следующие обозначения:


DBI-файл - “niss.dbi

DDI-файл - “niss_eng.ddi

DLL-файл - “niss_module.dll

EXE-модуль - “module.exe


Замечание: Вместо имени “module” используется имя конкретного модуля (в данном случае, используется имя “demo”).
Ниже приведена диаграмма, наглядно демонстрирующая процесс интеграции и взаимодействия модулей в системе Inspector+:



Диаграмма взаимосвязей модулей в системе Inspector+

Поясним назначение каждого объекта и смысл связей в данной диаграмме. DBI и DDI файлы содержат необходимую информацию по объектам системы Inspector+ (формат этих файлов описан ниже). DLL-файл отвечает за изменение параметров объектов и за сохранение их в базе данных. Также он обеспечивает работу с объектами: создание, изменение, удаление и некоторые другие специфические операции с объектами в дереве системы Inspector+. Позволяет пересылать параметры созданных или измененных объектов исполнительному модулю, информирует его об определенных действиях с объектами. Также в DLL-файле хранятся настроечные панели объектов. EXE-модуль отвечает за работу с оборудованием. Он выполняет опрос всех устройств и извещает ядро Inspector’а обо всех возникающих событиях, а также позволяет выполнять определенные действия с устройствами из системы Inspector+. Таким образом, осуществляется своего рода двусторонний обмен между ядром и модулем. Все события и действия должны быть обязательно зарегистрированы в системе (включены в DDI-файл). Остальные объекты из диаграммы в пояснении не нуждаются.



Примечание: DLL файл должен быть написан ТОЛЬКО на VC++ 6.0 c использованием MFC. Исполняемый файл может быть написан на чем угодно, в любой среде программирования (например, CBuilder или Delphi).


Пример реализации

К этой документации прилагаются два подробных примера. Первый из них создает объект SIMPLEDEMO, а второй DEMO. Первый представляет собой каркас без учета особенностей реализации с конкрентным оборудованием. Второй объект предусматривает наличие некого виртуального устройства, подключенного к COM-порту компьютера, и описывает взаимодействие системы Inspector+ с этим оборудованием. Ниже описывается создание второго варианта.


Примечание: Все необходимые модули и исходные файлы прилагаются к данному документу.
Допустим, в систему требуется интегрировать некое оборудование под названием “Demo”. Созданный модуль должен эмулировать работу с неким несуществующим оборудованием, которое включает в себя устройства с уникальными адресами, по которым будет осуществляться обращение к этим устройствам и происходить их опрос. Таким образом, в системе будет существовать конфигурация, состоящая из 2 основных объектов: родительского объекта DEMO с параметром COM-port и дочерних объектов DEMO_DEVICE с параметром Address. В системе будет существовать возможность для выполнения определенного набора действий с устройствами и передачи всех происходящих в них событий ядру системы Inspector+.


Этап 1


Добавим в DBI-файл 2 объекта с описанием всех параметров:


[OBJ_DEMO]

id, CHAR, 16

name, CHAR, 60

parent_id, CHAR, 16

port, CHAR, 5

flags, INTEGER


[OBJ_DEMO_DEVICE]

id, CHAR, 16

name, CHAR, 60

parent_id, CHAR, 16

address, INTEGER

flags, INTEGER


Каждый объект обязательно должен обладать 3 параметрами:
id – уникальный идентификатор объекта;

name – имя объекта;

parent_id – идентификатор родительского объекта;
Дополнительный параметр для объекта DEMO:
port - адрес COM-порта;
Дополнительный параметр для объекта DEMO_DEVICE:
address - адрес устройства;
Параметр flags используется для внутренних нужд системы и не может использоваться внешними приложениями.

Теперь запустите программу idb.exe (она находится в корневой папке Инспектора) и нажмите кнопку “Выбрать базу”.




Далее укажите путь к базе niss.mbd и нажмите кнопку “Обновить”.

Вся информация по объектам и значения всех их параметров сохраняется в базе данных Inspector’a.



Этап 2

Приступим теперь к редактированию DDI-файла. Для каждого объекта следует внести следующую информацию: имя объекта, события, действия и состояния объекта, правила переходов из одного состояния в другое по определенным событиям, а также присвоить каждому состоянию соответствующее имя bmp-файла без расширения. При этом берется та часть имени файла, которая описывает состояние объекта (см. замечание ниже). Изображения используются для отображения объектов на карте Inspector’a в зависимости от состояния объекта. BMP-файлы должны храниться в папке “\Bmp” в корневом каталоге Inspector’a. Итак, выполним следующее:




  • Добавим объекты DEMO и DEMO_DEVICE;

  • В разделе “Имена” определим названия объектов: “Demo” и “Demo Device”, соответственно;

  • В разделе “События” для объекта DEMO определим события:

    • LOST – Потеря связи;

    • RESTORE – Восстановление связи;

  • В разделе “События” для объекта DEMO_DEVICE определим события:

    • ON – Включено;

    • OFF – Выключено;

  • В разделе “Реакции” для объекта DEMO_DEVICE определим действия:

    • ON – Включить;

    • OFF – Выключить;

  • В разделе “Значки ” для объекта DEMO и DEMO_DEVICE определим имена объектов: “demo” и “demo_device”, соответственно.

  • В разделе “Состояния” для объекта DEMO определим состояния и соответствующие состояниям значки:

    • DETACHED – Потеря связи (с изображением “detach”);

    • NORMAL – Восстановление связи (с изображением “norm”);

  • В разделе “Состояния” для объекта DEMO_DEVICE определим состояния и соответствующие состояниям значки:

    • ON – Включено (с изображением “on”);

    • OFF – Выключено (с изображением “off”);

  • В разделе “Правила перехода” для объекта DEMO добавим правила:

    • DETACHED –> NORMAL;

    • NORMAL –> DETACHED;

  • В разделе “Правила перехода” для объекта DEMO_DEVICE добавим правила:

    • ON –> OFF;

    • OFF –> ON;

Для работы с DDI-файлом рекомендуется пользоваться программой “DDI Editor”, специально предназначенной для этой цели.


Замечание: Имя bmp-файла формируется следующим образом: “name_state.bmp”, где “name” - имя объекта, а “state” - соответствующее состояние объекта.

Этап 3

В прилагающихся к документации исходных файлах наглядно представлен пример DLL-файла. Ниже, кратко описан процесс создания DLL-файла и его состав.

Все объекты наследуются от класса NissObjectDLLExt с переопределением виртуальных методов этого класса.
Описание класса NissObjectDLLEx:
class NissObjectDLLExt

{

protected:



CoreInterface* m_pCore;

public:


NissObjectDLLExt(CoreInterface* core) { m_pCore = core; }
virtual CString GetObjectType() = 0;

virtual CString GetParentType() = 0;

virtual int GetPos() { return -1; }

virtual CString GetPort() { return CString(); }

virtual CString GetProcessName() { return CString(); }

virtual CString GetDeviceType() { return CString(); }


virtual BOOL HasChild() { return FALSE; }

virtual UINT HasSetupPanel() { return FALSE; }

virtual void OnPanelInit(CWnd*) {}

virtual void OnPanelLoad(CWnd*,Msg&) {}

virtual void OnPanelSave(CWnd*,Msg&) {}

virtual void OnPanelExit(CWnd*) {}

virtual void OnPanelButtonPressed(CWnd*,UINT) {}

virtual BOOL IsRegionObject() { return FALSE; }

virtual BOOL IsProcessObject() { return FALSE; }
virtual void OnCreate(Msg&) {}

virtual void OnChange(Msg&,Msg&) {}

virtual void OnDelete(Msg&) {}

virtual void OnInit(Msg&) {}

virtual void OnEnable(Msg&) {}

virtual void OnDisable(Msg&) {}

virtual BOOL OnEvent(Event&) { return FALSE; }

virtual BOOL OnReact(React&) { return FALSE; }

virtual BOOL IsIncludeParentId() { return 0; }

virtual BOOL IsWantAllEvents() { return 0; }

virtual CString DescribeSubscribeObjectsList() { return CString(); }

virtual CString GetIncludeIdParentType(){ return CString(); }

virtual CString DescribeParamLists(){ return CString(); }
};
CoreInterface* m_pCore – это указатель на интерфейс ядра. Интерфейс используется для обращения к ядру и отсылки ему сообщений, а также для получения параметров других объектов через методы CoreInterface.
Описание класса CoreInterface:
class CoreInterface

{

public:



virtual BOOL DoReact(React&) = 0;

virtual BOOL NotifyEvent(Event&) = 0;

virtual void SetupACDevice(LPCTSTR objtype, LPCTSTR objid, LPCTSTR objtype_reader) = 0;

virtual BOOL IsObjectExist(LPCTSTR objtype, LPCTSTR id) = 0;

virtual BOOL IsObjectDisabled(LPCTSTR objtype, LPCTSTR id) = 0;
virtual Msg FindPersonInfoByCard(LPCTSTR facility_code, LPCTSTR card) = 0;

virtual Cstring GetObjectName(LPCTSTR objtype, LPCTSTR id) = 0;

virtual Cstring GetObjectState(LPCTSTR objtype, LPCTSTR id) = 0;

virtual BOOL IsObjectState(LPCTSTR objtype, LPCTSTR id, CString state) = 0;


virtual Cstring GetObjectParam(LPCTSTR objtype, LPCTSTR id, LPCTSTR param) = 0;

virtual int GetObjectParamInt(LPCTSTR objtype, LPCTSTR id, LPCTSTR param) = 0;

virtual CMapStringToStringArray* GetObjectParamList(LPCTSTR objtype, LPCTSTR id, LPCTSTR param) = 0;

virtual CStringArray* GetObjectParamList(LPCTSTR objtype, LPCTSTR id, LPCTSTR param, LPCTSTR name) = 0;

virtual void GetObjectParams(LPCTSTR objtype, LPCTSTR id, Msg& msg) = 0;

virtual void SetObjectParamInt(LPCTSTR objtype, LPCTSTR id, LPCTSTR param, int val) = 0;

virtual Cstring GetObjectParentId(LPCTSTR objtype, LPCTSTR id, LPCTSTR parent) = 0;

virtual int GetObjectIds(LPCTSTR objtype, CStringArray& list, LPCTSTR main_id = NULL) = 0;

virtual int GetObjectChildIds(LPCTSTR objtype, LPCTSTR objid, LPCTSTR childtype, CStringArray& list) = 0;

};
Описание методов класса NissObjectDLLEx:


virtual BOOL IsWantAllEvents() – возвращает TRUE, если необходимо в функции OnEvent получать события от всех объектов, FALSE - если только от своего объекта.
virtual CString DescribeSubscribeObjectsList() – подписаться на объекты. Через запятую указываются типы объектов, при изменении которых (при нажатии на кнопке “Настройка”) произойдет уведомление об этом для текущего объекта и в модуле можно будет получить соответствующее событие. Например, если вернуть “CAM,GRABBER”, то при изменении настроек этих объектов для объекта “DEMO” придет сообщение типа:
“DEMO|1|UPDATE_CAM|параметры камеры”

и

“DEMO|1|UPDATE_GRABBER|параметры платы видеоввода”


virtual CString GetObjectType() – определяет тип объекта.
Пример:

virtual CString GetObjectType() { return "DEMO"; }


virtual CString GetParentType() – определяет тип родительского объекта.
Пример:

virtual CString GetParentType() { return "SLAVE"; }
virtual int GetPos() – возвращает позицию объекта в ключевом файле “key.iss”. Этот параметр должен быть согласован с компанией ISS.
Пример:

virtual int GetPos() { return 100; }
Если этот параметр вам еще не известен – отладку модуля осуществляйте в демо-режиме.
virtual CString GetPort() – возвращает номер порта, по которому будет происходить соединение и обмен между объектом и ядром. Этот параметр должен быть согласован с фирмой ISS.
Пример:

virtual CString GetPort() { return "1100"; }
virtual CString GetProcessName() – определяет имя процесса и используется ядром для поиска и автоматичского запуска исполнительного модуля при старте системы и инициализации модуля.
Пример:

virtual CString GetProcessName() { return "demo"; }
virtual CString GetDeviceType() – определяет тип объекта и характер его поведения. В зависимости от этого, ядро выбирает способ взаимодействия с объектом. Существует 3 известных типа объектов: “ACD”, “ACD2” и “ACR”. Тип “ACD” означает, что объект в дальнейшем будет получать все события, связанные с созданием, изменением и удалением следующих объектов: Пользователи, Временные зоны и Уровни доступа. Тип “ACD2” аналогичен типу “ACD”, только кроме этого, он еще указывает на то, что ядро обеспечит по мере необходимости автоматическое удаление временных карточек (карточек с ограниченным сроком действия). Тип “ACR” указывает на то, что объект является считывателем. Этот параметр будет непосредственно влиять на объект уровня доступа, точнее, это отразиться в его настройках: в выпадающем списке раздела “точка прохода” будет содержаться перечень всех созданных и определенных в системе объектов типа “ACR”.
virtual BOOL HasChild() – используется для определения, существует ли у данного объекта дочерний объект. Если у объекта имеется дочерний объект, метод возвращает TRUE, в противном случае, FALSE.
Пример:

virtual BOOL HasChild() { return TRUE; }
virtual UINT HasSetupPanel() – используется для определения, существует ли у данного объекта панель настроек (см. замечание ниже). Если у объекта имеется имеется панель настроек, метод возвращает TRUE, в противном случае, FALSE.
Пример:

virtual UINT HasSetupPanel() { return TRUE; }
virtual void OnPanelInit(CWnd*) – используется при инициализации панели настроек объекта. В качестве параметра передается указатель на окно панели настроек.

virtual void OnPanelLoad(CWnd*,Msg&) – используется при загрузке панели настроек для получения параметров объекта. В качестве параметра передается указатель на окно панели настроек и ссылка на сообщение, через которое осуществляется передача параметров объекта и заполнения ими необходимых полей в панели настроек.
Пример:

virtual void OnPanelLoad(CWnd* pwnd,Msg& params)

{

CString s;

s = params.GetParam("port");

pwnd->GetDlgItem(IDC_PORT)->SetWindowText(s);

}
virtual void OnPanelSave(CWnd*,Msg&) – используется при выгрузке панели настроек для сохранения параметров объекта. В качестве параметра передается указатель на окно панели настроек и ссылка на сообщение, через которое осуществляется передача параметров объекта и сохранение их в БД.
Пример:

virtual void OnPanelSave(CWnd* pwnd,Msg& params)

{

CString s;

pwnd->GetDlgItem(IDC_PORT)->GetWindowText(s);

params.SetParam("port",s);

}
virtual void OnPanelExit(CWnd*) – используется при закрытии панели настроек объекта. В качестве параметра передается указатель на окно панели настроек.

virtual void OnPanelButtonPressed(CWnd*,UINT) – предназначен для отработки нажатий кнопок на панели настроек объекта. В качестве параметра передается указатель на окно панели настроек и идентификатор кнопки. На идентификаторы всех кнопок накладываются определенные условия (см. замечание ниже).
Пример:

virtual void OnPanelButtonPressed(CWnd* pwnd,UINT id)

{

if(id==IDC_TEST)

{

React react("DEMO",Id,"TEST");

m_pCore->DoReact(react);

}

}
Если вы хотите по нажатию кнопки вывести какое-нибудь собственное диалоговое окно, созданное в этом же dll-файле, то необходимо предварительно использовать следующий код:
HINSTANCE prev_hinst = AfxGetResourceHandle();

HMODULE hRes = GetModuleHandle(“niss_demo.dll”);

if(hRes) AfxSetResourceHandle(hRes);
a затем уже показать это диалоговое окно:
СXXXDialog dlg;

dlg.DoModal();


и в заключение:
AfxSetResourceHandle(prev_hinst);
virtual BOOL IsRegionObject() – указывает на то, что объект будет поддерживать разделы Inspector’a. Разделы применяются для группирования объектов. Также они могут использоваться в системе отчетов.

virtual BOOL IsProcessObject() – указывает на то, что объект будет поддерживать возможность одновременного запуска и параллельной работы нескольких исполнительных модулей. Например, это может использоваться для запуска отдельного модуля непосредственно для каждого COM-порта. Старайтесь по возможности использовать всегда один рабочий модуль. Это упростит отладку и модификацию модуля.
virtual void OnCreate(Msg&) – используется при создании объекта. В качестве параметра передается ссылка на сообщение, содержащая информацию по объекту. Здесь же указывются параметры по умолчанию.
Пример:

virtual void OnCreate(Msg& msg)

{

msg.SetParam("port","COM1");

}
virtual void OnInit(Msg&) – используется при инициализации объекта. В качестве параметра передается ссылка на сообщение, содержащая информацию по объекту.
Пример:

virtual void OnInit(Msg& msg)

{

OnChange(msg, msg);

}
virtual void OnChange(Msg&,Msg&) – используется при изменении объекта. В качестве параметра передаются ссылки на сообщения, содержащие информацию по объекту до и после изменения, соответственно.
Пример:

virtual void OnChange(Msg& msg, Msg& prev)

{

React react(msg.GetSourceType(),msg.GetSourceId(),"INIT");

react.SetParam("port",msg.GetParam("port"));

m_pCore->DoReact(react);

}
virtual void OnDelete(Msg&) – используется при удалении объекта. В качестве параметра передается ссылка на сообщение, содержащая информацию по объекту.
Пример:

virtual void OnDelete(Msg& msg)

{

React react(msg.GetSourceType(),msg.GetSourceId(),"EXIT");

m_pCore->DoReact(react);

}
virtual void OnEnable(Msg&) – предназначен для отработки нажатия кнопки “Disable”(“Выключить”) на панели Inspector’a при включении объекта. В качестве параметра передается ссылка на сообщение, содержащая информацию по объекту.
virtual void OnDisable(Msg&) – предназначен для отработки нажатия кнопки “Disable”(“Выключить”) на панели Inspector’a при выключении объекта. В качестве параметра передается ссылка на сообщение, содержащая информацию по объекту.
virtual BOOL OnEvent(Event&) – предназначен для обработки событий, передаваемых в качестве параметра.
Пример:

virtual BOOL OnEvent(Event& event)

{

if(event.GetAction() == "ACCESS_IN" ||

event.GetAction() == "ACCESS_OUT")

{

Msg per = m_pCore->FindPersonInfoByCard(event.GetParam("facility_code"),event.GetParam("card"));

event.SetParam("param0", !per.GetSourceId().IsEmpty() ?

per.GetParam("name") : event.GetParam("facility_code") + event.GetParam("card"));

event.SetParam("param1", per.GetSourceId() );

}

else

if(event.GetAction() == "NOACCESS_CARD")

{

event.SetParam("param0",event.GetParam("facility_code") + event.GetParam("card"));

}



return TRUE;

}
virtual BOOL OnReact(React&) – предназначен для обработки реакций, передаваемых в качестве параметра.
Замечание 1: Все панели настроек объектов хранятся в ресурсах в виде диалогов. Причем, идентификаторы диалогов строятся по схеме IDD_object_SETUP, где object - это имя соответствующего объекта. Например, для объекта DEMO – это IDD_DEMO_SETUP, а для объекта DEMO_DEVICE – это IDD_DEMO_DEVICE _SETUP.
Замечание 2: Числовые значения идентификаторов кнопок должны начинаться с номера 1151. Например, для кнопки “Test” идентификатор в файле “Resource.h” определяется так:

#define IDC_TEST 1151


Замечание 3: Для того, чтобы в дереве настроек у объекта отображался свой собственный значок, необходимо в ресурсах DLL-файла создать BITMAP размером 14x14 с именем объекта. В данном случае “DEMO” и “DEMO_DEVICE”, соответственно.
В глобальной функции CreateNissObject(CoreInterface* core) необходимо создать экзепляры описанных объектов, поместить их в массив CNissObjectDLLExtArray и возвратить указатель на объект этого массива. Через эту же функцию получаем указатель на интерфейс ядра, который в дальнейшем используется в объектах (в данном случае в объектах DEMO и DEMO_DEVICE) для обращения к методам данного интерфейса. В дальнейшем, после загрузки DLL-файла ядро вызывает функцию CreateNissObject и получает указатели на все используемые объекты.
CNissObjectDLLExtArray* APIENTRY CreateNissObject(CoreInterface* core)

{

CNissObjectDLLExtArray* ar = new CNissObjectDLLExtArray;


ar->Add(new NissObjectDemo(core));

ar->Add(new NissObjectDemoDevice(core));


return ar;

}

Этап 4

Процесс создания модулей, взаимодействующих с ядром, подробно рассмотрен в документации по IIDK. Необходимую информацию можно также почерпнуть из примера, исходные файлы которого прилагаются к данной документации. Ниже, кратко изложены основные моменты, отражающие основную суть реализации модуля и его взаимодействия с ядром.
В начале происходит установление связи с ядром:
BOOL Connect(LPCTSTR ip, LPCTSTR port, LPCTSTR id, void (_stdcall *func)(LPCTSTR msg)) – осуществляет подсоединение к ядру.
Параметры функции:

LPCTSTR ip - ip адрес машины с ядром

LPCTSTR port - порт протокола TCP/IP, через которое происходит подключение.

900 для видеоподсистемы, 1030 для ActiveX.

LPCTSTR id - идентификатор подключения, для видео >1 , для Activex = id ActiveX в дереве

настроек.

void (_stdcall *func)(LPCTSTR msg)) – callback функция, которая принимает сообщения от Инспектора.
В конце, соответственно, происходит разрыв связи:
void Disconnect(LPCTSTR id) – осуществляет отключение от ядра.
Параметры функции:

LPCTSTR id – идентификатор подключения, указанный ранее при вызове функции Connect.


Все сообщения от ядра отрабатываются в специальной call-back функции:
void (_stdcall *func)(LPCTSTR msg)) – callback функция, принимающая сообщения от Inspector'а.
Пример объявления функции:

void _stdcall myfunc(LPCTSTR str)

{

printf("\r\nReceived:%s\r\n\r\n",str);



}
Сообщения для ядра передаются следующим образом:
BOOL SendMsg(LPCTSTR id, LPCTSTR msg) – осуществляет отправку сообщения Inspector'у.
Параметры:

LPCTSTR id - идентификатор подключения, указанный ранее при вызове функции Connect

LPCTSTR msg – текст сообщения.
Возвращаемое значение:

TRUE в случае удачной посылки сообщения,

FALSE в случае неудачи.
Примеры передачи сообщений:

SendMsg(id,”CAM|1|REC”); // поставить камеру 1 на запись

SendMsg(id, "DEMO|1|RESTORE"); // восстановление связи объектом DEMO

SendMsg(id,"DEMO_DEVICE|1|ON|params<1>,param0_name

,param0_val<1>"); // включить устройство DEMO_DEVICE с адресом 1
Для реализации взаимодействия модуля и ядра используются следующие файлы:
Состав IIDK

Iidk.dll – библиотека функций для интеграции с Inspector’ом.

Iidk.h - заголовочный файл с объявлениями импортируемых функций

Iidk.lib - lib файл для работы с iidk.dll (lib для MS Visual C++)

Msg.h - файл ,содержащий класс для извлечения параметров объектов
К документации прилагаются следующие файлы:
Niss.dbi

Niss_eng.ddi

Niss_demo.dll с исходными файлами проекта

Demo.exe с исходными файлами проекта

Ddi.exe - программа DDI Editor
Замечание: В отличие от стандартного подключения к ядру Inspector’a в данном случае IIDK Interface в системе не создается. В качестве идентификатора подключения передается пустая строка, то есть id равен “”.
При выгрузке модуля ему посылается сообщение WM_EXIT:

#define WM_EXIT (WM_USER+2000)

при помощи функции WinAPI PostThreadMessage.

Необходимо перехватить это сообщение и обеспечить “правильную” выгрузку своего модуля. Например в VC++ и MFC, это событие отлавливается в классе, наследуемым от CWinApp, в Delphi и СBuilder - TApplication.







База данных защищена авторским правом ©uverenniy.ru 2016
обратиться к администрации

    Главная страница