搜索
您的当前位置:首页正文

动环监控系统中B接口的实现

来源:爱够旅游网
动环监控系统中B接⼝的实现

动环监控系统简述

1.术语介绍

1.1 省集中监控中⼼-Province Supervision Center(PSC)

⾯向多FSU管理的⾼级监控层次,即省集中监控中⼼,通过开放的数据协议,连接监控范围内的FSU。1.2 现场监控单元-Field supervision unit(FSU)

监控系统的最⼩管理⼦系统,由若⼲监控模块和其它辅助设备组成,⾯向直接的设备数据采集、处理的监控层次,可以包含采样、数据处理、数据中继等功能,监控范围⼀般为⼀个独⽴的通信局(站)或⼤型局(站)内相对独⽴的电源、空调设备及环境。1.3 监控对象 Supervision Object(SO)被监控的各种电源、空调设备及机房环境。1.4 B接⼝

为省集中监控中⼼(PSC)与现场监控单元(FSU)之间的接⼝。(即FSU的北向接⼝)

2. 接⼝⽹络结构

FSU与PSC之间通过WebService和FTP⽅式互联,⼆者同时形成完整的B接⼝协议标准。

B接⼝在嵌⼊式arm监控主机上的实现

环境

宿主机平台:Ubuntu 16.04.6⽬标机平台:iMX6UL

交叉编译:gcc-linaro-4.9-2014.11 arm-linux-gnueabihf-gcc SOAP/XML 关于C/C++ 语⾔的实现 gsoap_2.8.83 XML数据的⽣成和解析 XML数据的⽣成和解析 libxml2 结合主要开发为C环境且尽量占⽤较少资源,推荐使⽤minixmlXML数据的⽣成和解析 minixml

1. gsaop ⽣成 B接⼝报⽂协议 C代码框架

gSOAP编译⼯具提供了⼀个SOAP/XML 关于C/C++ 语⾔的实现,从⽽让C/C++语⾔开发web服务或客户端程序的⼯作变得轻松了很多。绝⼤多数的C++web服务⼯具包提供⼀组API函数类库来处理特定的SOAP数据结构,这样就使得⽤户必须改变程序结构来适应相关的类库。与之相反,gSOAP利⽤技术提供了⼀组透明化的SOAP API,并将与开发⽆关的SOAP实现细节相关的内容对⽤户隐藏起来。1.1 gsaop在linux下的安装gsoap安装编译依赖

sudo apt-get install build-essential libgtk2.0-dev libglib2.0-dev checkinstall m4 flex bison automake autoconf openssl libssl-dev

为了成功编译gSOAP,您需要安装GTK+的开发⽂件和GLib库(libraries)。

安装Checkinstall以便管理您系统中直接由源代码编译安装的软件。

安装YACC,YACC是Unix/Linux上⼀个⽤来⽣成编译器的编译器(编译器代码⽣成器),sudo apt-get install flex bison安装OpenSSL,web通信的加密(https)及鉴权 sudo apt-get install openssl libssl-dev

安装编译步骤: 解压

unzip gsoap_2.8.83.zipmkdir gsoap_installcd gsoap-2.8/

配置安装路径、编译、安装

./configure --prefix=/home/wangh/workspace/wh_tools/gsoap_installsudo make

sudo make install

使⽤gsoap⽣成 fsu 代码框架

新建gsoap_fsu⽂件夹,从gsoap_install⽂件夹中拷贝以下⽂件bin/soapcpp2 bin/wsdl2hgsoap2.8/gsoap/typemap.datcustom和import⽂件夹

1.使⽤wsdl2h⼯具,根据WSDL产⽣头⽂件,执⾏以下命令

./wsdl2h -P -x -c -s -t ./typemap.dat -o fsu.h FSUService.wsdl

其中-c为产⽣纯c代码,默认⽣成 c++代码;

-x 不产⽣xml⽂件(可⽤可不⽤,xml有⼀定帮助,但是太多);-s为不使⽤STL库,-t为typemap.dat的标识。详情可通过wsdl2h.exe -help查看帮助。

这⾥的WSDL⽂件,可以在wsdl2h命令中在线下载,也可以先下载到本地,然后引⽤本地WSDL⽂件,我这⾥是采⽤本地⽂件⽅式。

2. 使⽤soapcpp2⼯具,根据头⽂件 fsu.h 产⽣框架代码,执⾏以下命令

./soapcpp2 -2 -L -c -x -I import:custom fsu.h

-2 ⽣成 SOAP 1.2

-L 不⽣成客户端、服务器库⽂件-c 为产⽣纯c代码,默认⽣成 c++代码-I path 引⽤⽂件路径

3. 提取有效核⼼代码⽤于应⽤编程,应⽤⼯程使⽤⽂件如下:

2. B接⼝报⽂协议分析与实现

2.1 SOAP函数接⼝分析

根据 FSUService.wsdl ⽣成 soap API 如下,在 soapStub.h 的最后定义

我们不⽤去关⼼ SOAP 接⼝的实现细节,直接调⽤对应 API 即可实现客户端与服务器的 xml 数据收发。客户端接⼝过程:

soap_call_ns1__invoke() 在客户端调⽤,实现发送和接收(它调⽤send和recv);服务器接⼝过程:

soap_serve() 服务器调⽤,部署 SOAP 服务器,它会调⽤soap_serve_request(),当收到 ns1:invoke 的请求时,服务器调⽤ soap_serve_ns1__invoke(),在调⽤应⽤层⽤户接⼝ ns1__invoke(),来获取接收数据和填充应答数据。2.2 SOAP通信简单⽰例 我的⼯程⽬录如下图所⽰:

客户端程序:

/**

*********************************************************************************** @file main.c

* @brief soap客户端测试程序

* @details 基于东环监控 B 接⼝的soap客户端程序

* @author wanghuan any question please send mail to 371463817@qq.com* @date 2019-06-17* @version V1.0

* @copyright Copyright (c) 2019-2022 江苏亨通光⽹科技有限公司***********************************************************************************/

#include \"soapH.h\"#include \"stdsoap2.h\"#include #include #include

#include \"FSUServiceSoapBinding.nsmap\"int main(int argc, char **argv){

// struct soap fsuSoap;// soap_init(&fsuSoap);

struct soap *fsuSoap = soap_new();

fsuSoap->send_timeout = fsuSoap->recv_timeout = 5; //soap发送、接收超时 fsuSoap->transfer_timeout = 30; //soap消息传输超时 soap_set_namespaces(fsuSoap, namespaces);// soap_set_mode(fsuSoap, SOAP_C_NOIOB);

struct ns1__invokeResponse soap_tmp_ns1__invokeResponse; char * soap_tmp_SOAP_ENC__string;

soap_default_ns1__invokeResponse(fsuSoap, &soap_tmp_ns1__invokeResponse); soap_tmp_SOAP_ENC__string = NULL;

soap_tmp_ns1__invokeResponse._invokeReturn = &soap_tmp_SOAP_ENC__string; // ⼿动组成LOGIN的xml数据字符串 char xmlData[500];

memset(xmlData, 0x00, sizeof(xmlData));

strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\");

strcat(xmlData, \"LOGIN\\n\"); strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\");

strcat(xmlData, \"123\\n\"); strcat(xmlData, \"123\\n\"); strcat(xmlData, \"10004\\n\");

strcat(xmlData, \"192.168.1.124\\n\"); strcat(xmlData, \"10000\\n\"); strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\");

printf(\"soap_tmp_ns1__invoke._xmlData:\\n\"); printf(\"%s\", xmlData);

// saop 客户端程序

// char * server_addr = \"http://10.10.62.83:8080/HT_SC/services/SCService\"; char * server_addr = \"http://192.168.1.123:8080\";

int iRet = soap_call_ns1__invoke(fsuSoap, server_addr, NULL, xmlData, soap_tmp_ns1__invokeResponse._invokeReturn); if ( iRet == SOAP_ERR) {

printf(\"Error while calling the soap_call_ns1__invoke\"); } else {

printf(\"Calling the soap_call_ns1__invoke success。\\n\");

printf(\"%s\\n\", *soap_tmp_ns1__invokeResponse._invokeReturn); } return 0;}

服务端程序:

/**

*********************************************************************************** @file main.c

* @brief soap服务端测试程序

* @details 基于东环监控 B 接⼝的soap服务器程序

* @author wanghuan any question please send mail to 371463817@qq.com* @date 2019-06-17* @version V1.0

* @copyright Copyright (c) 2019-2022 江苏亨通光⽹科技有限公司***********************************************************************************/

#include \"soapH.h\"#include \"stdsoap2.h\"#include #include #include

#include \"FSUServiceSoapBinding.nsmap\"

/**

* 启动soap服务器*/

int main(int argc, char **argv){

SOAP_SOCKET iSocket_master, iSocket_slave; struct soap *fsuSoap = soap_new(); //新建soap

fsuSoap->send_timeout = fsuSoap->recv_timeout = 5; //soap发送、接收超时 fsuSoap->transfer_timeout = 30; //soap消息传输超时// soap_set_mode(fsuSoap, SOAP_C_NOIOB);

// saop 服务器程序 8080为端⼝号,最后⼀个参数不重要。

iSocket_master = soap_bind(fsuSoap, NULL, 8080, 100); //绑定到相应的IP地址和端⼝()NULL指本机,然后监听 if (iSocket_master< 0) //绑定出错 {

soap_print_fault(fsuSoap, stderr); exit(-1); }

printf(\"SoapBind success,the master socket number is:%d\\n\",iSocket_master); //绑定成功返回监听套接字

while(1) {

iSocket_slave = soap_accept(fsuSoap); //收到套接字连接 if(iSocket_slave < 0) {

soap_print_fault(fsuSoap, stderr); exit(-1); }

//客户端的IP地址

fprintf(stderr,\"Accepted connection fromIP= %d.%d.%d.%d socket = %d \\n\", \\

((fsuSoap->ip)>>24)&&0xFF,((fsuSoap->ip)>>16)&0xFF,((fsuSoap->ip)>>8)&0xFF,(fsuSoap->ip)&0xFF,(fsuSoap->socket)); printf(\"Socket connect success,the slave socket number is:%d\\n\",iSocket_slave); soap_serve(fsuSoap);

printf(\"soap_serve end...\");

soap_end(fsuSoap); //服务器出错才到这⼀步 }

soap_done(fsuSoap); free(fsuSoap); return 0;}

/**

* soap服务器⽤户数据处理函数

* @param[in] *_xmlData 接收客户端的xml格式字符串* @param[out] **_invokeReturn 服务器要回复⼤数据* @return SOAP_OK or error code*/

SOAP_FMAC5 int SOAP_FMAC6 ns1__invoke(struct soap* soap, char *_xmlData, char **_invokeReturn){

printf(\"ns1__invoke _xmlData\\n\"); printf(\"%s\\n\", _xmlData);

char xmlData[500];

memset(xmlData, 0, sizeof(xmlData));

strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\");

strcat(xmlData, \"LOGIN_ACK\\n\"); strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\");

strcat(xmlData, \"\\n\"); strcat(xmlData, \"\\n\"); strcat(xmlData, \"\");

*_invokeReturn = xmlData;

// *_invokeReturn = \"\\n\\n\\nLOGIN_ACK\\n\\n\\n\\n\\n\"; printf(\"_invokeReturn _xmlData\\n\"); printf(\"%s\\n\", *_invokeReturn); return SOAP_OK;}

程序makefile:

顶层Makefile与Makefile.inc

DIRS :=

DIRS += sc_clientDIRS += sc_server#DIRS += xml_test

# Dummy targets for building and clobbering everything in all subdirectoriesall:

@ for dir in ${DIRS}; do (cd $${dir}; ${MAKE}) ; doneclean:

@ for dir in ${DIRS}; do (cd $${dir}; ${MAKE} clean) ; done

Makefile.inc

SHELL = /bin/bash#CC := gcc -m32#CPP := g++#LD := ld#AR := ar#STRIP := strip

CC := arm-linux-gnueabihf-gccCPP := arm-linux-gnueabihf-g++LD := arm-linux-gnueabihf-ldAR := arm-linux-gnueabihf-arSTRIP := arm-linux-gnueabihf-strip

# -DWITH_DOM -DWITH_OPENSSL两个宏是链接openssl时要⽤的;

# -DDEBUG宏⽤于开启SOAP协议收发⽇志,⽇志存于⽂件RECV.log、SENT.log、TEST.log之中CFLAGS += -c -g -Wall

#CFLAGS += -DWITH_DOM -DWITH_OPENSSLCFLAGS += -std=gnu99

CFLAGS += -DWITH_NO_C_LOCALE#CFLAGS += -WITH_NONAMESPACESCFLAGS += $(INCLUDE)# openssl⽬录名OPENSSL_DIR :=

#OPENSSL_DIR += ../openssl

# 源⽂件

SOURCES_FSU :=

SOURCES_FSU += ../soap_sc/soapC.cSOURCES_FSU += ../soap_sc/soapClient.c#SOURCES_FSU += ../soap_sc/soapServer.cSOURCES_FSU += ../soap_sc/stdsoap2.cSOURCES_COMM :=

# ⽬标⽂件

OBJECTS_FSU := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_FSU)))

OBJECTS_COMM := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_COMM)))# 头⽂件路径

INCLUDE += -I../soap_sc/ \\ -I../minixml/ \\

# -I../libxml2/include \\# -I../tinyxml2/ \\# -I../comm/ \\

# -I$(OPENSSL_DIR)/include \\# 共享库链接OpenSSL

#LDLIBS += -L$(OPENSSL_DIR)/lib \\# -lssl \\# -lcrypto \\

# 静态库链接OpenSSL

#LDLIBS += $(OPENSSL_DIR)/lib/libssl.a \\# $(OPENSSL_DIR)/lib/libcrypto.a \\# -ldl \\

# 静态库链接libxml2

#LDLIBS += ../libxml2/libxml2.a \\# -lm

# 静态库链接minixml

LDLIBS += ../minixml/libmxml.a#LDLIBS += -lmxml # 链接库(其他)

LDLIBS += -lpthread

%.o: %.cpp

@echo \" CPP \" $@;

@$(CPP) $(CFLAGS) -c -o $@ $<%.o: %.c

@echo \" CC \" $@;

@$(CC) $(CFLAGS) -c -o $@ $<.PHONY: all clean

客户端client的Makefile

include ../Makefile.incPROGRAM = fsucSOURCES += main.c

OBJECTS := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES)))

all: $(OBJECTS_FSU) $(OBJECTS_COMM) $(OBJECTS)

$(CC) -o $(PROGRAM) $(OBJECTS_FSU) $(OBJECTS_COMM) $(OBJECTS) $(LDLIBS)clean:

rm -f $(OBJECTS_FSU) rm -f $(OBJECTS_COMM) rm -f $(OBJECTS) rm -f $(PROGRAM)

编译之后 先执⾏服务端程序,在执⾏客户端程序服务端收到request

客户端发送request,并收到response

接下来开始尝试使⽤ libxml2 库⽣成和解析 xml

2.3 libxml2安装移植(改⽤minixml)新建安装⽂件夹,这样⽅便我们提取库⽂件使⽤

mkdir /home/wangh/workspace/wh_tools/libxml-install

编写安装及配置脚本 wh_configure.sh 如下:

#!/bin/sh

#sh⽂件需设置可执⾏权限 chmod +x wh_configure.sh#--prefix=PATH,指定make install时⽬标⽂件存放路径PREFIX=/home/wangh/workspace/wh_tools/libxml-install#--host=target-platform 指定⽬标平台HOST=arm-linux#交叉编译绝对路径

CC_DIR=/home/wangh/Tools/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc#编译配置

#sudo ./configure --prefix=$PREFIX --host=$HOST CC=$CC_DIR --with-python=/home/wangh/workspace/wh_tools/libxml2-2.9.9/python

#编译时由于提⽰没有python相关的头⽂件出错,⼜因为项⽬中不使⽤python相关的内容,所以没有讲python进库中,读者应该按照⾃⼰的需要要配置该选项。对于zlib同样的道理,--without-zlib不添加会编译出错sudo ./configure --prefix=$PREFIX --host=$HOST --target=arm CC=$CC_DIR --without-zlib --without-pythonsudo make

sudo make install

执⾏安装脚本2.4 minixml安装移植

是⼀个⼩型的开源的XML解析器,采⽤ C 语⾔开发。该解析器最⼤的特点就是⼩型、⽆须依赖其他类库,在嵌⼊式系统中,minixml解析器很⼩巧(200k多点),很常⽤。

待续。。。。。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top