熟悉了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 <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
-
- #include <sys/socket.h>
- #include <net/if.h>
- #include <net/route.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
- #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 <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- #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
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。