热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

onvif笔记二(discoveryserver)

熟悉了gsoap之后,开始做onvif的第一步:discovery源码路径:http:download.csdn.netdetaillishuanglin1314758455

熟悉了gsoap之后,开始做onvif的第一步:discovery

源码路径:http://download.csdn.net/detail/lishuanglin131/4758455


1、生成头文件。

执行wsdl中“gen-h - 副本.bat”,可以得到onvif.h文件。

执行wsdl中“gen-c - 副本.bat”,可以得到相关的.c、xml等文件。


2、编写discoveryServer.c

#include "onvif.nsmap"
#include "soapH.h"
#include "soapStub.h"



//////////////////////////////////////////////////////////////////////////////////////////////////////
//主函数
int main(int argc,char ** argv)
{
        struct soap ServerSoap;
        struct ip_mreq mcast;
        int count = 0;

        //初始话运行时环境
        //soap_init2(&ServerSoap, SOAP_IO_UDP | SOAP_IO_FLUSH | SOAP_IO_LENGTH, SOAP_IO_UDP | SOAP_IO_FLUSH | SOAP_IO_LENGTH);
        soap_init1(&ServerSoap, SOAP_IO_UDP | SOAP_XML_IGNORENS);
//      ServerSoap.version = 2;
//      soap_init(&ServerSoap);
//      ServerSoap.accept_timeout = 10;
//      ServerSoap.recv_timeout = 10;

        soap_set_namespaces(&ServerSoap, namespaces);

        if(!soap_valid_socket(soap_bind(&ServerSoap, NULL, 3702, 10)))
        {
                soap_print_fault(&ServerSoap, stderr);
                exit(1);
        }

        mcast.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
        mcast.imr_interface.s_addr = htonl(INADDR_ANY);

        if(setsockopt(ServerSoap.master, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast)) <0)
        {
                printf("setsockopt error! error code = %d,err string = %s\n",errno,strerror(errno));
                return 0;
        }

        for(;;)
        {
                if(soap_serve(&ServerSoap))
                {
                        soap_print_fault(&ServerSoap, stderr);
                }

                soap_destroy(&ServerSoap);
                soap_end(&ServerSoap);

                //客户端的IP地址
                printf("Accepted count %d, connection from IP = %lu.%lu.%lu.%lu socket = %d \r\n",
                                count, ((ServerSoap.ip)>>24)&0xFF, ((ServerSoap.ip)>>16)&0xFF, ((ServerSoap.ip)>>8)&0xFF, (ServerSoap.ip)&0xFF, (ServerSoap.socket));
                count++;
        }

        //分离运行时的环境
        soap_done(&ServerSoap);

        return 0;
}

3、编写function.c文件

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 

#include "soapH.h"
#include "soapStub.h"


static char szDevXAddr[1024];
static char szEndpointReference[1024];
static char tmpBuf[1024];
static struct d__ScopesType scopes;
#define METADATA_VERSION    1


#define ONVIF_SERVER_CALL()    printf("onvifs: call %s, path=%s\r\n", __FUNCTION__, soap->path)

#define ONVIF_RETURN_OK(soap, namespaces)   \
	ONVIF_SERVER_CALL();    \
	if(namespaces!=NULL) soap_set_namespaces(soap, namespaces);  \
	return SOAP_OK;



static inline int onvif_receiver_fault_subcode_oom(struct soap *soap)
{
	return soap_receiver_fault_subcode(soap, "ter:OutofMemory", "Out of Memory", "The device does not have sufficient memory to complete the action.");
}


/****************************** 具体服务方法 ******************************/
SOAP_FMAC5 int SOAP_FMAC6 __dndl__Probe(struct soap* soap, struct d__ProbeType *d__Probe, struct d__ProbeMatchesType *d__ProbeMatches)
{
	char MessageID[128] = {0};
	int MatchingRuleNotSupported = 0;

	printf("__dndl__Probe %s from %s\n", d__Probe->Types?d__Probe->Types:"Any types", inet_ntoa(soap->peer.sin_addr));

	if (soap->header)
	{
#if 0
		uuid_t uuid;

		uuid_generate(uuid);
		strcpy(MessageID, "urn:uuid:");
		uuid_unparse(uuid, MessageID+9);
#else
		unsigned char mac[6] = {0};
		netGetMac("eth3", mac);
		struct timeval tv, tv1;
		gettimeofday(&tv, NULL);
		usleep(1);
		gettimeofday(&tv1, NULL);
		sprintf(MessageID, "urn:uuid:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
			(int)tv.tv_usec, (int)(tv.tv_usec&0xFFFF), (int)(tv1.tv_usec&0xFFFF), (int)(tv.tv_usec&0xFF), (int)(tv1.tv_usec&0xFF), mac[0]&0xFF, mac[1]&0xFF, mac[2]&0xFF, mac[3]&0xFF, mac[4]&0xFF, mac[5]&0xFF);
#endif
		if(soap->header->wsa__MessageID)
		{
			printf("remote wsa__MessageID : %s\n",soap->header->wsa__MessageID);
			soap->header->wsa__RelatesTo = (struct wsa__Relationship*)soap_malloc(soap, sizeof(struct wsa__Relationship));
			if(soap->header->wsa__RelatesTo==NULL)
				return onvif_receiver_fault_subcode_oom(soap);
			soap_default__wsa__RelatesTo(soap, soap->header->wsa__RelatesTo);
			soap->header->wsa__RelatesTo->__item = soap->header->wsa__MessageID;

			soap->header->wsa__MessageID = soap_strdup(soap, MessageID);
			soap->header->wsa__To = (char*)"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
			if(MatchingRuleNotSupported)
				soap->header->wsa__Action = (char*)"http://schemas.xmlsoap.org/ws/2005/04/discovery/fault";
			else
				soap->header->wsa__Action = (char*)"http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches";
		}
	}


	d__ProbeMatches->__sizeProbeMatch = 1;
	d__ProbeMatches->ProbeMatch = (struct d__ProbeMatchType*)soap_malloc(soap, sizeof(struct d__ProbeMatchType));
	if(d__ProbeMatches->ProbeMatch)
	{
		unsigned int localIp = 0;
		netGetIp("eth3", &localIp);
		sprintf(szDevXAddr, "http://%s/onvif/device_service", inet_ntoa(*((struct in_addr *)&localIp)));

		soap_default_d__ScopesType(soap, &scopes);
		sprintf(tmpBuf, "%s", "onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/hardware/IPC-model onvif://www.onvif.org/name/IPC-model");
		scopes.__item = tmpBuf;

		soap_default_d__ProbeMatchType(soap, d__ProbeMatches->ProbeMatch);
		sprintf(szEndpointReference, MessageID);//"urn:uuid:11223344-5566-7788-99aa-000c29ebd542");
		d__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address = szEndpointReference;//"urn:uuid:464A4854-4656-5242-4530-313035394100";
		d__ProbeMatches->ProbeMatch->Types = (char*)"dn:NetworkVideoTransmitter";
		d__ProbeMatches->ProbeMatch->Scopes = &scopes;
		d__ProbeMatches->ProbeMatch->XAddrs = szDevXAddr;//"http://192.168.7.98/onvif/device_service";
		d__ProbeMatches->ProbeMatch->MetadataVersion = METADATA_VERSION;

		return SOAP_OK;
	}
	else
	{
		return onvif_receiver_fault_subcode_oom(soap);
	}
}


SOAP_FMAC5 int SOAP_FMAC6 __dnrd__Hello(struct soap* soap, struct d__HelloType *d__Hello, struct d__ResolveType *dn__HelloResponse)
{
	ONVIF_RETURN_OK(soap, NULL);
}


SOAP_FMAC5 int SOAP_FMAC6 __dnrd__Bye(struct soap* soap, struct d__ByeType *d__Bye, struct d__ResolveType *dn__ByeResponse)
{
	ONVIF_RETURN_OK(soap, NULL);
}



int netGetMac(char *pInterface, unsigned char *pMac)
{
	struct ifreq ifreq;
	int sockfd = 0;
	unsigned char mac[6] = {0}; 

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <0)
	{/*创建套接口,后用于获取mac地址*/
		perror("netGetMac socket");
		return -1;
	}

	strcpy(ifreq.ifr_name, pInterface);

	if(ioctl(sockfd, SIOCGIFHWADDR, &ifreq) <0)
	{/*获取mac地址*/
		perror("netGetMac ioctl");
		close(sockfd);
		return -2;
	}

	memcpy(mac, ifreq.ifr_hwaddr.sa_data, 6);/*复制mac地址到mac*/
	printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

	if(pMac != NULL)
	{
		memcpy(pMac, mac, 6);
	}

	close(sockfd);

	return 0;
}

/* 获取Ip */
int netGetIp(char *pInterface, unsigned int *ip)
{
	int sock = 0;
	struct ifreq ifr;

	if((pInterface == NULL) || (*pInterface == '\0'))
	{
		printf("get ip: pInterface == NULL\r\n");
		return -1;
	}

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, pInterface, IFNAMSIZ);
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if(sock <= 0)
	{
		printf("get ip: sock error, %s\r\n", strerror(errno));
		return -1;
	}

	((struct sockaddr_in*)&ifr.ifr_addr)->sin_family = PF_INET;
	if(ioctl(sock, SIOCGIFADDR, &ifr) <0)
	{
		printf("get ip error: %s\r\n", strerror(errno));
		close(sock);
		return -1;
	}
	else
	{
		*ip = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr;
		printf("get ip(%d:%d:%d:%d) success!\r\n", (*ip)&0xff, (*ip>>8)&0xff, (*ip>>16)&0xff, (*ip>>24)&0xff);
	}
	close(sock);

	return 0;
}

4、编写discoveryClient.c文件

#include  
#include  
#include  
#include 
#include "onvif.nsmap"
#include "soapH.h"
#include "soapStub.h" 

int main()
{
	struct soap *soap; 
	int result = 0; 
	struct d__ProbeType req;
	struct d__ProbeMatchesType resp;
	struct d__ScopesType sScope;
	struct SOAP_ENV__Header header;
	int count = 0;
//	char guid_string[100];
//	uuid_t uuid;
	soap = soap_new(); 
	if(soap == NULL)
	{
		printf("sopa new error\r\n");
		return -1;
	}

	/* discovery test */
//	uuid_generate(uuid);
//	uuid_unparse(uuid, guid_string);
	soap_set_namespaces(soap, namespaces); 

	//超过5秒钟没有数据就退出
	soap->recv_timeout = 5;
	soap_default_SOAP_ENV__Header(soap, &header);
#if 0
	header.wsa__MessageID = guid_string;
	header.wsa__To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";
	header.wsa__Action = "http://schemas.xmllocal_soap.org/ws/2005/04/discovery/Probe";
#endif
	soap->header = &header;
	soap_default_d__ScopesType(soap, &sScope);
	sScope.__item = "";
	soap_default_d__ProbeType(soap, &req);
	req.Scopes = &sScope;
	req.Types =NULL;

	int i = 0;
	do
	{
		soap_call___dndl__Probe(soap, "soap.udp://239.255.255.250:3702/datagram", NULL, &req, &resp); 
		printf("002.1 \n");

		if (soap->error) { 
			printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); 
			result = soap->error; 
			break;
		} 
		else
		{

			//printf("soap_call___dndl__Probe __sizeProbeMatch=%d\r\n",resp.__sizeProbeMatch);

//			while(1)
			{
				printf("Target EP Address       : %s\r\n", resp.ProbeMatch[i].wsa__EndpointReference.Address);
				printf("Target Type             : %s\r\n", resp.ProbeMatch[i].Types);
				printf("Target Service Address  : %s\r\n", resp.ProbeMatch[i].XAddrs);
				i++;
			}
			//printf("Target Metadata Version : %d\r\n", resp.ProbeMatch[0].ns2__MetadataVersion);
			//printf("Target Scopes Address   : %s\r\n", resp.ProbeMatch[0].ns2__Scopes->__item);
		}
	}while(0);
	soap_destroy(soap); // remove deserialized class instances (C++ only)
	soap_end(soap); // clean up and remove deserialized data

	////////////////////////////////////////////////////////////////////////////
failed:
	soap_free(soap);//detach and free runtime context
	soap_done(soap); // detach context (last use and no longer in scope)

	return result; 
}

5、编写makefile文件

GSOAP_ROOT = /mnt/hgfs/work/onvif/gsoap-2.8/gsoap
CC = gcc -g -O2 #-DWITH_OPENSSL -DHAVE_PTHREAD_H
INCLUDE = -I$(GSOAP_ROOT)
SERVER_OBJS = soapC.o soapServer.o stdsoap2.o function.o webServer.o
SERVER_SSL_OBJS = soapC.o soapServer.o stdsoap2.o function.o webServerSsl.o
DISCOVER_SERVER_OBJS = soapC.o soapServer.o stdsoap2.o function.o discoveryServer.o
DISCOVER_CLIENT_OBJS = soapC.o soapClient.o stdsoap2.o function.o discoveryClient.o


all: discoverServer discoverClient server

discoverServer: $(DISCOVER_SERVER_OBJS)
        $(CC) -o discoveryServer $(DISCOVER_SERVER_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto

discoverClient: $(DISCOVER_CLIENT_OBJS)
        $(CC) -o discoveryClient $(DISCOVER_CLIENT_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto

server: $(SERVER_OBJS)
        $(CC) -o webServer $(SERVER_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto

serverSsl: $(SERVER_SSL_OBJS)
        $(CC) -o webServerSsl $(SERVER_SSL_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto

clean:
        rm -f *.o *.a discoveryServer discoveryClient webServer webServerSsl



推荐阅读
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 本文由编程笔记小编整理,主要介绍了使用Junit和黄瓜进行自动化测试中步骤缺失的问题。文章首先介绍了使用cucumber和Junit创建Runner类的代码,然后详细说明了黄瓜功能中的步骤和Steps类的实现。本文对于需要使用Junit和黄瓜进行自动化测试的开发者具有一定的参考价值。摘要长度:187字。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了一种求解最小权匹配问题的方法,使用了拆点和KM算法。通过将机器拆成多个点,表示加工的顺序,然后使用KM算法求解最小权匹配,得到最优解。文章给出了具体的代码实现,并提供了一篇题解作为参考。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 本文主要介绍了gym102222KVertex Covers(高维前缀和,meet in the middle)相关的知识,包括题意、思路和解题代码。题目给定一张n点m边的图,点带点权,定义点覆盖的权值为点权之积,要求所有点覆盖的权值之和膜qn小于等于36。文章详细介绍了解题思路,通过将图分成两个点数接近的点集L和R,并分别枚举子集S和T,判断S和T能否覆盖所有内部的边。文章还提到了使用位运算加速判断覆盖和推导T'的方法。最后给出了解题的代码。 ... [详细]
author-avatar
握住每一缕光
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有