打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
onvif 笔记二(discovery server)

熟悉了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

  1. #include "onvif.nsmap"  
  2. #include "soapH.h"  
  3. #include "soapStub.h"  
  4.   
  5.   
  6.   
  7. //////////////////////////////////////////////////////////////////////////////////////////////////////  
  8. //主函数  
  9. int main(int argc,char ** argv)  
  10. {  
  11.         struct soap ServerSoap;  
  12.         struct ip_mreq mcast;  
  13.         int count = 0;  
  14.   
  15.         //初始话运行时环境  
  16.         //soap_init2(&ServerSoap, SOAP_IO_UDP | SOAP_IO_FLUSH | SOAP_IO_LENGTH, SOAP_IO_UDP | SOAP_IO_FLUSH | SOAP_IO_LENGTH);  
  17.         soap_init1(&ServerSoap, SOAP_IO_UDP | SOAP_XML_IGNORENS);  
  18. //      ServerSoap.version = 2;  
  19. //      soap_init(&ServerSoap);  
  20. //      ServerSoap.accept_timeout = 10;  
  21. //      ServerSoap.recv_timeout = 10;  
  22.   
  23.         soap_set_namespaces(&ServerSoap, namespaces);  
  24.   
  25.         if(!soap_valid_socket(soap_bind(&ServerSoap, NULL, 3702, 10)))  
  26.         {  
  27.                 soap_print_fault(&ServerSoap, stderr);  
  28.                 exit(1);  
  29.         }  
  30.   
  31.         mcast.imr_multiaddr.s_addr = inet_addr("239.255.255.250");  
  32.         mcast.imr_interface.s_addr = htonl(INADDR_ANY);  
  33.   
  34.         if(setsockopt(ServerSoap.master, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast)) < 0)  
  35.         {  
  36.                 printf("setsockopt error! error code = %d,err string = %s\n",errno,strerror(errno));  
  37.                 return 0;  
  38.         }  
  39.   
  40.         for(;;)  
  41.         {  
  42.                 if(soap_serve(&ServerSoap))  
  43.                 {  
  44.                         soap_print_fault(&ServerSoap, stderr);  
  45.                 }  
  46.   
  47.                 soap_destroy(&ServerSoap);  
  48.                 soap_end(&ServerSoap);  
  49.   
  50.                 //客户端的IP地址  
  51.                 printf("Accepted count %d, connection from IP = %lu.%lu.%lu.%lu socket = %d \r\n",  
  52.                                 count, ((ServerSoap.ip)>>24)&0xFF, ((ServerSoap.ip)>>16)&0xFF, ((ServerSoap.ip)>>8)&0xFF, (ServerSoap.ip)&0xFF, (ServerSoap.socket));  
  53.                 count++;  
  54.         }  
  55.   
  56.         //分离运行时的环境  
  57.         soap_done(&ServerSoap);  
  58.   
  59.         return 0;  
  60. }  

3、编写function.c文件

  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <unistd.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6.   
  7. #include <sys/types.h>  
  8. #include <sys/stat.h>  
  9. #include <sys/ioctl.h>  
  10. #include <fcntl.h>  
  11.   
  12. #include <sys/socket.h>  
  13. #include <net/if.h>  
  14. #include <net/route.h>  
  15. #include <netinet/in.h>  
  16. #include <arpa/inet.h>  
  17.   
  18. #include "soapH.h"  
  19. #include "soapStub.h"  
  20.   
  21.   
  22. static char szDevXAddr[1024];  
  23. static char szEndpointReference[1024];  
  24. static char tmpBuf[1024];  
  25. static struct d__ScopesType scopes;  
  26. #define METADATA_VERSION    1  
  27.   
  28.   
  29. #define ONVIF_SERVER_CALL()    printf("onvifs: call %s, path=%s\r\n", __FUNCTION__, soap->path)  
  30.   
  31. #define ONVIF_RETURN_OK(soap, namespaces)   \  
  32.     ONVIF_SERVER_CALL();    \  
  33.     if(namespaces!=NULL) soap_set_namespaces(soap, namespaces);  \  
  34.     return SOAP_OK;  
  35.   
  36.   
  37.   
  38. static inline int onvif_receiver_fault_subcode_oom(struct soap *soap)  
  39. {  
  40.     return soap_receiver_fault_subcode(soap, "ter:OutofMemory", "Out of Memory", "The device does not have sufficient memory to complete the action.");  
  41. }  
  42.   
  43.   
  44. /****************************** 具体服务方法 ******************************/  
  45. SOAP_FMAC5 int SOAP_FMAC6 __dndl__Probe(struct soap* soap, struct d__ProbeType *d__Probe, struct d__ProbeMatchesType *d__ProbeMatches)  
  46. {  
  47.     char MessageID[128] = {0};  
  48.     int MatchingRuleNotSupported = 0;  
  49.   
  50.     printf("__dndl__Probe %s from %s\n", d__Probe->Types?d__Probe->Types:"Any types", inet_ntoa(soap->peer.sin_addr));  
  51.   
  52.     if (soap->header)  
  53.     {  
  54. #if 0  
  55.         uuid_t uuid;  
  56.   
  57.         uuid_generate(uuid);  
  58.         strcpy(MessageID, "urn:uuid:");  
  59.         uuid_unparse(uuid, MessageID+9);  
  60. #else  
  61.         unsigned char mac[6] = {0};  
  62.         netGetMac("eth3", mac);  
  63.         struct timeval tv, tv1;  
  64.         gettimeofday(&tv, NULL);  
  65.         usleep(1);  
  66.         gettimeofday(&tv1, NULL);  
  67.         sprintf(MessageID, "urn:uuid:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",  
  68.             (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);  
  69. #endif  
  70.         if(soap->header->wsa__MessageID)  
  71.         {  
  72.             printf("remote wsa__MessageID : %s\n",soap->header->wsa__MessageID);  
  73.             soap->header->wsa__RelatesTo = (struct wsa__Relationship*)soap_malloc(soap, sizeof(struct wsa__Relationship));  
  74.             if(soap->header->wsa__RelatesTo==NULL)  
  75.                 return onvif_receiver_fault_subcode_oom(soap);  
  76.             soap_default__wsa__RelatesTo(soap, soap->header->wsa__RelatesTo);  
  77.             soap->header->wsa__RelatesTo->__item = soap->header->wsa__MessageID;  
  78.   
  79.             soap->header->wsa__MessageID = soap_strdup(soap, MessageID);  
  80.             soap->header->wsa__To = (char*)"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";  
  81.             if(MatchingRuleNotSupported)  
  82.                 soap->header->wsa__Action = (char*)"http://schemas.xmlsoap.org/ws/2005/04/discovery/fault";  
  83.             else  
  84.                 soap->header->wsa__Action = (char*)"http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches";  
  85.         }  
  86.     }  
  87.   
  88.   
  89.     d__ProbeMatches->__sizeProbeMatch = 1;  
  90.     d__ProbeMatches->ProbeMatch = (struct d__ProbeMatchType*)soap_malloc(soap, sizeof(struct d__ProbeMatchType));  
  91.     if(d__ProbeMatches->ProbeMatch)  
  92.     {  
  93.         unsigned int localIp = 0;  
  94.         netGetIp("eth3", &localIp);  
  95.         sprintf(szDevXAddr, "http://%s/onvif/device_service", inet_ntoa(*((struct in_addr *)&localIp)));  
  96.   
  97.         soap_default_d__ScopesType(soap, &scopes);  
  98.         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");  
  99.         scopes.__item = tmpBuf;  
  100.   
  101.         soap_default_d__ProbeMatchType(soap, d__ProbeMatches->ProbeMatch);  
  102.         sprintf(szEndpointReference, MessageID);//"urn:uuid:11223344-5566-7788-99aa-000c29ebd542");  
  103.         d__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address = szEndpointReference;//"urn:uuid:464A4854-4656-5242-4530-313035394100";  
  104.         d__ProbeMatches->ProbeMatch->Types = (char*)"dn:NetworkVideoTransmitter";  
  105.         d__ProbeMatches->ProbeMatch->Scopes = &scopes;  
  106.         d__ProbeMatches->ProbeMatch->XAddrs = szDevXAddr;//"http://192.168.7.98/onvif/device_service";  
  107.         d__ProbeMatches->ProbeMatch->MetadataVersion = METADATA_VERSION;  
  108.   
  109.         return SOAP_OK;  
  110.     }  
  111.     else  
  112.     {  
  113.         return onvif_receiver_fault_subcode_oom(soap);  
  114.     }  
  115. }  
  116.   
  117.   
  118. SOAP_FMAC5 int SOAP_FMAC6 __dnrd__Hello(struct soap* soap, struct d__HelloType *d__Hello, struct d__ResolveType *dn__HelloResponse)  
  119. {  
  120.     ONVIF_RETURN_OK(soap, NULL);  
  121. }  
  122.   
  123.   
  124. SOAP_FMAC5 int SOAP_FMAC6 __dnrd__Bye(struct soap* soap, struct d__ByeType *d__Bye, struct d__ResolveType *dn__ByeResponse)  
  125. {  
  126.     ONVIF_RETURN_OK(soap, NULL);  
  127. }  
  128.   
  129.   
  130.   
  131. int netGetMac(char *pInterface, unsigned char *pMac)  
  132. {  
  133.     struct ifreq ifreq;  
  134.     int sockfd = 0;  
  135.     unsigned char mac[6] = {0};   
  136.   
  137.     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
  138.     {/*创建套接口,后用于获取mac地址*/  
  139.         perror("netGetMac socket");  
  140.         return -1;  
  141.     }  
  142.   
  143.     strcpy(ifreq.ifr_name, pInterface);  
  144.   
  145.     if(ioctl(sockfd, SIOCGIFHWADDR, &ifreq) < 0)  
  146.     {/*获取mac地址*/  
  147.         perror("netGetMac ioctl");  
  148.         close(sockfd);  
  149.         return -2;  
  150.     }  
  151.   
  152.     memcpy(mac, ifreq.ifr_hwaddr.sa_data, 6);/*复制mac地址到mac*/  
  153.     printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);  
  154.   
  155.     if(pMac != NULL)  
  156.     {  
  157.         memcpy(pMac, mac, 6);  
  158.     }  
  159.   
  160.     close(sockfd);  
  161.   
  162.     return 0;  
  163. }  
  164.   
  165. /* 获取Ip */  
  166. int netGetIp(char *pInterface, unsigned int *ip)  
  167. {  
  168.     int sock = 0;  
  169.     struct ifreq ifr;  
  170.   
  171.     if((pInterface == NULL) || (*pInterface == '\0'))  
  172.     {  
  173.         printf("get ip: pInterface == NULL\r\n");  
  174.         return -1;  
  175.     }  
  176.   
  177.     memset(&ifr, 0, sizeof(ifr));  
  178.     strncpy(ifr.ifr_name, pInterface, IFNAMSIZ);  
  179.     sock = socket(AF_INET, SOCK_DGRAM, 0);  
  180.     if(sock <= 0)  
  181.     {  
  182.         printf("get ip: sock error, %s\r\n", strerror(errno));  
  183.         return -1;  
  184.     }  
  185.   
  186.     ((struct sockaddr_in*)&ifr.ifr_addr)->sin_family = PF_INET;  
  187.     if(ioctl(sock, SIOCGIFADDR, &ifr) < 0)  
  188.     {  
  189.         printf("get ip error: %s\r\n", strerror(errno));  
  190.         close(sock);  
  191.         return -1;  
  192.     }  
  193.     else  
  194.     {  
  195.         *ip = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr;  
  196.         printf("get ip(%d:%d:%d:%d) success!\r\n", (*ip)&0xff, (*ip>>8)&0xff, (*ip>>16)&0xff, (*ip>>24)&0xff);  
  197.     }  
  198.     close(sock);  
  199.   
  200.     return 0;  
  201. }  

4、编写discoveryClient.c文件

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #include <stdint.h>  
  5. #include "onvif.nsmap"  
  6. #include "soapH.h"  
  7. #include "soapStub.h"   
  8.   
  9. int main()  
  10. {  
  11.     struct soap *soap;   
  12.     int result = 0;   
  13.     struct d__ProbeType req;  
  14.     struct d__ProbeMatchesType resp;  
  15.     struct d__ScopesType sScope;  
  16.     struct SOAP_ENV__Header header;  
  17.     int count = 0;  
  18. //  char guid_string[100];  
  19. //  uuid_t uuid;  
  20.     soap = soap_new();   
  21.     if(soap == NULL)  
  22.     {  
  23.         printf("sopa new error\r\n");  
  24.         return -1;  
  25.     }  
  26.   
  27.     /* discovery test */  
  28. //  uuid_generate(uuid);  
  29. //  uuid_unparse(uuid, guid_string);  
  30.     soap_set_namespaces(soap, namespaces);   
  31.   
  32.     //超过5秒钟没有数据就退出  
  33.     soap->recv_timeout = 5;  
  34.     soap_default_SOAP_ENV__Header(soap, &header);  
  35. #if 0  
  36.     header.wsa__MessageID = guid_string;  
  37.     header.wsa__To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery";  
  38.     header.wsa__Action = "http://schemas.xmllocal_soap.org/ws/2005/04/discovery/Probe";  
  39. #endif  
  40.     soap->header = &header;  
  41.     soap_default_d__ScopesType(soap, &sScope);  
  42.     sScope.__item = "";  
  43.     soap_default_d__ProbeType(soap, &req);  
  44.     req.Scopes = &sScope;  
  45.     req.Types =NULL;  
  46.   
  47.     int i = 0;  
  48.     do  
  49.     {  
  50.         soap_call___dndl__Probe(soap, "soap.udp://239.255.255.250:3702/datagram", NULL, &req, &resp);   
  51.         printf("002.1 \n");  
  52.   
  53.         if (soap->error) {   
  54.             printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));   
  55.             result = soap->error;   
  56.             break;  
  57.         }   
  58.         else  
  59.         {  
  60.   
  61.             //printf("soap_call___dndl__Probe __sizeProbeMatch=%d\r\n",resp.__sizeProbeMatch);  
  62.   
  63. //          while(1)  
  64.             {  
  65.                 printf("Target EP Address       : %s\r\n", resp.ProbeMatch[i].wsa__EndpointReference.Address);  
  66.                 printf("Target Type             : %s\r\n", resp.ProbeMatch[i].Types);  
  67.                 printf("Target Service Address  : %s\r\n", resp.ProbeMatch[i].XAddrs);  
  68.                 i++;  
  69.             }  
  70.             //printf("Target Metadata Version : %d\r\n", resp.ProbeMatch[0].ns2__MetadataVersion);  
  71.             //printf("Target Scopes Address   : %s\r\n", resp.ProbeMatch[0].ns2__Scopes->__item);  
  72.         }  
  73.     }while(0);  
  74.     soap_destroy(soap); // remove deserialized class instances (C++ only)  
  75.     soap_end(soap); // clean up and remove deserialized data  
  76.   
  77.     ////////////////////////////////////////////////////////////////////////////  
  78. failed:  
  79.     soap_free(soap);//detach and free runtime context  
  80.     soap_done(soap); // detach context (last use and no longer in scope)  
  81.   
  82.     return result;   
  83. }  

5、编写makefile文件

  1. GSOAP_ROOT = /mnt/hgfs/work/onvif/gsoap-2.8/gsoap  
  2. CC = gcc -g -O2 #-DWITH_OPENSSL -DHAVE_PTHREAD_H  
  3. INCLUDE = -I$(GSOAP_ROOT)  
  4. SERVER_OBJS = soapC.o soapServer.o stdsoap2.o function.o webServer.o  
  5. SERVER_SSL_OBJS = soapC.o soapServer.o stdsoap2.o function.o webServerSsl.o  
  6. DISCOVER_SERVER_OBJS = soapC.o soapServer.o stdsoap2.o function.o discoveryServer.o  
  7. DISCOVER_CLIENT_OBJS = soapC.o soapClient.o stdsoap2.o function.o discoveryClient.o  
  8.   
  9.   
  10. all: discoverServer discoverClient server  
  11.   
  12. discoverServer: $(DISCOVER_SERVER_OBJS)  
  13.         $(CC) -o discoveryServer $(DISCOVER_SERVER_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto  
  14.   
  15. discoverClient: $(DISCOVER_CLIENT_OBJS)  
  16.         $(CC) -o discoveryClient $(DISCOVER_CLIENT_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto  
  17.   
  18. server: $(SERVER_OBJS)  
  19.         $(CC) -o webServer $(SERVER_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto  
  20.   
  21. serverSsl: $(SERVER_SSL_OBJS)  
  22.         $(CC) -o webServerSsl $(SERVER_SSL_OBJS) $(INCLUDE) -lpthread -lssl -lcrypto  
  23.   
  24. clean:  
  25.         rm -f *.o *.a discoveryServer discoveryClient webServer webServerSsl  


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
onvif开发总结
gsoap使用方法及心得(二)
ONVIF协议网络摄像机
onvif服务器篇之设备发现(onvifdiscover)
[转载]蓝牙4.0 BLE center与peripheral建立连接绑定过程
WEBSERVICE
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服