Getting ipc camera ability of onvif client under Linux: GetCapabilities

GetCapabilities: access to capabilities. The main purpose is to access device capability information (access to media service address)

Authentication: however, authentication is required before calling to acquire device capabilities. According to the ONVIF protocol, some interfaces need authentication, and some interfaces don't need authentication. If you don't use authentication when you call an interface that needs authentication, the interface call will fail. One way to implement authentication is to call the soap > WSSE > Add > usernametokenddigest() function in the gSOAP source code. To install the dependency library OpenSSL

Implementation code:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <assert.h>
  5  
  6 #include "soapH.h"
  7 #include "stdsoap2.h"
  8 #include "soapStub.h"
  9 #include "wsseapi.h"
 10  
 11 #include "wsdd.nsmap" //Namespace
 12  
 13 static struct soap* ONVIF_Initsoap(struct SOAP_ENV__Header *header, const char *was_To, const char *was_Action, int timeout)
 14 {
 15     struct soap *soap = NULL;    // soap environment variable
 16     unsigned char macaddr[6];
 17     char _HwId[1024];
 18     unsigned int Flagrand;
 19  
 20     soap = soap_new();
 21     if(soap == NULL)
 22     {
 23         printf("[%d]soap = NULL\n", __LINE__);
 24         return NULL;
 25     }
 26  
 27     soap_set_namespaces(soap, namespaces);   // Set up soap Of namespaces,Set namespace
 28  
 29     // Set timeout (exit without data after the specified time)
 30     if(timeout > 0)
 31     {
 32         soap->recv_timeout = timeout;
 33         soap->send_timeout = timeout;
 34         soap->connect_timeout = timeout;
 35     }
 36     else
 37     {
 38         //Maximum waittime : 20s
 39         soap->recv_timeout  = 20;
 40         soap->send_timeout  = 20;
 41         soap->connect_timeout = 20;
 42     }
 43  
 44     soap_default_SOAP_ENV__Header(soap, header);
 45  
 46     //Create SessionID randomly,generate uuid(windows Call down guid,linux Call down uuid),Format is urn:uuid:8-4-4-4-12,Randomly generated by the system
 47     srand((int)time(0));
 48     Flagrand = rand()%9000 + 8888;
 49     macaddr[0] = 0x1;
 50     macaddr[1] = 0x2;
 51     macaddr[2] = 0x3;
 52     macaddr[3] = 0x4;
 53     macaddr[4] = 0x5;
 54     macaddr[5] = 0x6;
 55     sprintf(_HwId, "urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X", Flagrand, macaddr[0], macaddr[1], macaddr[2],macaddr[3],macaddr[4],macaddr[5]);
 56     header->wsa__MessageID = (char *)malloc(100);  
 57     memset(header->wsa__MessageID, 0, 100);
 58     strncpy(header->wsa__MessageID, _HwId, strlen(_HwId));    //wsa__MessageID What is stored is uuid
 59  
 60     if(was_Action != NULL)
 61     {
 62         header->wsa__Action = (char*)malloc(1024);
 63         memset(header->wsa__Action, '\0', 1024);
 64         strncpy(header->wsa__Action, was_Action, 1024); //
 65     }
 66     if(was_To != NULL)
 67     {
 68         header->wsa__To = (char *)malloc(1024);
 69         memset(header->wsa__To, '\0', 1024);
 70         strncpy(header->wsa__To, was_To, 1024);//"urn:schemas-xmlsoap-org:ws:2005:04:discovery";
 71     }
 72     soap->header = header;
 73     return soap;
 74 }
 75  
 76  
 77 //Release function
 78 void ONVIF_soap_delete(struct soap *soap)
 79 {
 80     soap_destroy(soap);                      // remove deserialized class instances (C++ only)
 81     soap_end(soap);                          // Clean up deserialized data (except class instances) and temporary data
 82     soap_free(soap);                         // Reset and deallocate the context created with soap_new or soap_copy
 83 }
 84  
 85  
 86 //authentication
 87 static int ONVIF_SetAuthInfo(struct soap *soap, const char *username, const char *password)
 88 {
 89     int result = 0;
 90     if((NULL != username) || (NULL != password)){
 91         soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);
 92     }else{
 93         printf("un etAuth\n");
 94         result = -1;
 95     }
 96  
 97     return result;
 98 }
 99  
100  
101  
102 int main(int argc,char *argv[])
103 {
104     int ret = 0;
105     char sercer_addr[] = "http://172.168.0.211/onvif/device_service"; //Address from device search
106  
107     struct SOAP_ENV__Header header;
108     struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
109  
110     struct _tds__GetCapabilities *req;
111     struct _tds__GetCapabilitiesResponse *Response;
112     
113     if(NULL == (req = (struct _tds__GetCapabilities *)calloc(1,sizeof(struct _tds__GetCapabilities))))
114     {
115         printf("calloc is error \n");
116         ret = -1;
117         return ret;
118     }else{
119         req->__sizeCategory = 1;
120         req->Category = (enum tt__CapabilityCategory *)soap_malloc(soap, sizeof(int));
121         *(req->Category) = (enum tt__CapabilityCategory)5; //5 Express: tt__CapabilityCategory__Media
122  
123         ONVIF_SetAuthInfo(soap,"admin","hk123456");  //Authentication, enter the user name and password of the camera
124         ret = soap_call___tds__GetCapabilities(soap, sercer_addr, NULL,req, Response);
125         if(soap->error){ 
126             ret = -1;
127             printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
128             return ret;
129         }else{;
130             if(NULL != Response->Capabilities)
131             {
132                 if (Response->Capabilities->Media != NULL){
133                     if (Response->Capabilities->Media->XAddr != NULL){
134                         printf(" media_addr: %s \n", Response->Capabilities->Media->XAddr); 
135                     }
136                 }
137             }
138         }
139     }
140  
141     if(NULL != req)
142     {
143         free(req);
144         req = NULL;
145     }
146  
147     ONVIF_soap_delete(soap);
148     return ret;
149 }

 

Before compiling, copy these. c and some matching. h to the current working directory: stdsoap2.c soapC.c md5.c dom.c mecevp.c smdevp.c threads.c wsaapi.c wsseapi.c soapClient.c.

 

 

If the following error occurs, add: - dwith ﹣ OpenSSL during compilation

/tmp/cccao7U5.o: in the function 'soap · MEC · init':
mecevp.c:(.text+0xe): undefined reference to 'soap? SSL? Init'
/tmp/ccV2yl3Q.o: in the function 'soap? SMD? Init':
smdevp.c:(.text+0x24c): undefined reference to 'soap? SSL? Init'

 

 

Compilation: GCC - O test get ﹣ URI ﹣ test. C stdsoap2. C soapc. C MD5. C dom. C mecevp. C smdevp. C threads. C wsaapi. C wsseapi. C SoapClient. C - I import / - dwith ﹣ OpenSSL - lssl - lcrypto - LDL - pthread

Result: successfully get the media address we want

Tags: C OpenSSL SSL Windows Linux

Posted on Fri, 29 Nov 2019 08:30:42 -0800 by mikeyandyou