天天看點

win7下vs中實作onvif discovery(用戶端、服務端)

 完整代碼:http://download.csdn.net/detail/shenhuaikun/5234203

github:完整代碼

用gosap生成C代碼架構在這裡忽略。

1.服務端需要添加的代碼:首先對Probe、Hello、Bye進行了定義,然後對編寫main函數。

//#include <uuid/uuid.h>
#include "soapH.h"
#include "soapStub.h"



SOAP_FMAC5 int SOAP_FMAC6 __dndl__Probe(struct soap* soap, struct d__ProbeType *d__Probe, struct d__ProbeMatchesType *d__ProbeMatches)
{
 static struct d__ProbeMatchType ProbeMatch;
 static struct d__ScopesType scopes;
    static char MessageID[100];
    static char szXAddr[64];
    static char szEndpointReference[64];
    static struct wsa__Relationship wsa_RelatesTo;


    unsigned char MacAddr[8] ={0x00, 0x16, 0xe8, 0x53, 0x13, 0xc7};
    int localIP = inet_addr("192.168.7.33");  //0x6207A8C0
    //localIP = niGetLocalIPAddr(g_netEthNi);
    //memcpy(MacAddr, niGetHwAddr(g_netEthNi), 6);


    //    if(d__Probe->Types && strcasecmp(d__Probe->Types,"dn:NetworkVideoTransmitter")==0)


    sprintf(szXAddr, "http://%s/onvif/device_service", inet_ntoa(*((struct in_addr *)&localIP)));
 sprintf(szEndpointReference, "urn:uuid:11229344-5566-7788-99aa-%02x%02x%02x%02x%02x%02x",
                        MacAddr[0],MacAddr[1],MacAddr[2],MacAddr[3],MacAddr[4],MacAddr[5]);


 printf("__dndl__Probe %p, %p, %d\n", d__ProbeMatches, d__ProbeMatches->ProbeMatch, d__ProbeMatches->__sizeProbeMatch);
 soap_default_d__ProbeMatchType(soap, &ProbeMatch);
 soap_default_d__ScopesType(soap, &scopes);
 
 if (soap->header)
 {
        //uuid_t uuid;
  
        //uuid_generate(uuid);
        strcpy(MessageID, "urn:uuid:");//urn:uuid:
        //uuid_unparse(uuid, MessageID+9);


  if(soap->header->wsa__MessageID)
  {
   //printf("remote wsa__MessageID : %s\n",soap->header->wsa__MessageID);
    soap->header->wsa__RelatesTo =&wsa_RelatesTo;
   soap_default__wsa__RelatesTo(soap, soap->header->wsa__RelatesTo);
   soap->header->wsa__RelatesTo->__item = soap->header->wsa__MessageID;


   soap->header->wsa__MessageID = MessageID;
   soap->header->wsa__To = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
   soap->header->wsa__Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches";
  }
 }


 scopes.__item =  "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";
 
 ProbeMatch.wsa__EndpointReference.Address = szEndpointReference;                 //"urn:uuid:464A4854-4656-5242-4530-313035394100";
 ProbeMatch.Types = "dn:NetworkVideoTransmitter";
 ProbeMatch.Scopes = &scopes;
 ProbeMatch.XAddrs = szXAddr;                                                    //"http://192.168.7.97/onvif/device_service";
 ProbeMatch.MetadataVersion = 1;


 d__ProbeMatches->__sizeProbeMatch = 1;
 d__ProbeMatches->ProbeMatch = &ProbeMatch;


    return SOAP_OK;
}


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


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



int main(int argc, char *argv[])
{
 struct soap soap;
 struct ip_mreq mcast;
 int count=1;
 
 soap_init2(&soap, SOAP_IO_UDP|SOAP_IO_FLUSH, SOAP_IO_UDP|SOAP_IO_FLUSH);
 
    soap_set_namespaces(&soap, namespaces); 
 //soap_set_mode(&soap, SOAP_C_UTFSTRING);
 
 if(!soap_valid_socket(soap_bind(&soap, NULL, 3702, 10)))
 { 
  soap_print_fault(&soap, stderr);
  exit(1);
 }
 
 mcast.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
 mcast.imr_interface.s_addr = htonl(INADDR_ANY);
 if(setsockopt(soap.master, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast)) < 0)
 {
  printf("setsockopt error!\n");
  return 0;
 } 


 for(;;)
 { 
  printf("Now Accepting requests...waiting\n");
  if(soap_serve(&soap))
   soap_print_fault(&soap, stderr);
 
  soap_destroy(&soap);
  soap_end(&soap);


  printf("用戶端的IP位址:\n");
  printf("Accepted count:%d, connection from IP = %lu.%lu.%lu.%lu socket = %d \r\n",
    count, ((soap.ip)>>24)&0xFF, ((soap.ip)>>16)&0xFF, ((soap.ip)>>8)&0xFF, (soap.ip)&0xFF, (soap.socket));
  count++;
  printf("====================================================================\r\n");


 }
 
 soap_done(&soap);
 
 return 0;
}


           

2.用戶端需要生成的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
//#include <stdint.h>
//#include <uuid/uuid.h>


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


int main(int argc, char *argv[])
{
    //struct soap discovery_soap; 
    struct soap *soap; 
    int result = 0; 
 struct d__ProbeType req;
 struct d__ProbeMatchesType resp;
 struct d__ScopesType sScope;
 struct SOAP_ENV__Header header;                                                            //soap header
 int count = 0;
// struct SOAP_ENV__Header header;
 char guid_string[100];
    //uuid_t uuid;
    
    //soap_init(&discovery_soap); 
    //soap = &discovery_soap; 



    soap = soap_new();                                                                                         //init soap
    if(soap==NULL)
        return -1;


    
    // discovery test
 //uuid_generate(uuid);
    //uuid_unparse(uuid, guid_string);


//    soap_omode(soap, SOAP_IO_FLUSH|SOAP_IO_STORE);
    soap_set_namespaces(soap, namespaces); 
 //超過5秒鐘沒有資料就退出
 soap->recv_timeout = 5;


 soap_default_SOAP_ENV__Header(soap, &header);                                //init soap header
 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";
 soap->header = &header;                                                                                 //bind the soap header for transport                                    


  soap_default_d__ScopesType(soap, &sScope);
 sScope.__item = "";
 //sScope.__item = "onvif://www.onvif.org";


  soap_default_d__ProbeType(soap, &req);
 req.Scopes = &sScope;
 req.Types = "";
 //req.Types = "dn:NetworkVideoTransmitter";


 do
 {
  soap_call___dndl__Probe(soap, "soap.udp://239.255.255.250:3702/datagram", NULL, &req, &resp);


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


    //if(soap->header->wsa__RelatesTo && soap->header->wsa__RelatesTo->__item)
     //printf("RelatesTo   : %s\r\n", soap->header->wsa__RelatesTo->__item);


    if(soap->header->wsa__To)
     printf("To          : %s\r\n", soap->header->wsa__To);


    if(soap->header->wsa__Action)
     printf("Action      : %s\r\n", soap->header->wsa__Action);
   printf("====================================================================\r\n");
    
   printf("soap_call___dndl__Probe __sizeProbeMatch=%d\r\n",resp.__sizeProbeMatch);
   printf("Target EP Address       : %s\r\n", resp.ProbeMatch[0].wsa__EndpointReference.Address);
   printf("Target Type             : %s\r\n", resp.ProbeMatch[0].Types);
   printf("Target Service Address  : %s\r\n", resp.ProbeMatch[0].XAddrs);
   printf("Target Metadata Version : %d\r\n", resp.ProbeMatch[0].MetadataVersion);
   printf("Target Scopes Address   : %s\r\n", resp.ProbeMatch[0].Scopes->__item);
   printf("====================================================================\r\n");
  }
 }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; 
}

           

3.運作服務端:

win7下vs中實作onvif discovery(用戶端、服務端)

在ONVIF Device Test Tool中能被發現:

win7下vs中實作onvif discovery(用戶端、服務端)

此時的服務端運作:

win7下vs中實作onvif discovery(用戶端、服務端)

此時運作用戶端:

win7下vs中實作onvif discovery(用戶端、服務端)

服務端的:

win7下vs中實作onvif discovery(用戶端、服務端)

 以上完整代碼用于搜尋特定的真實裝置應該是搜不到的,搜特定的裝置需要閱讀自己生成的架構裡面的函數、方法,想要搜到特定的裝置應該要修改soap_call___dndl__Probe,還有printf函數裡的結構體的指向吧,具體看自己的函數方法,有時還要

考慮是否在同一段網。