Search code examples
cgsoaponvifws-discovery

ONVIF WS-Discover 1.0 - Client and Event Handlers


In my onvif client application I'm looking to implement the WS-Discovery with gsoap and wsddapi.c, but I have problems with the handler. I can send multicast message over UDP with soap_wsdd_probe (wsddapi.c), I have implemented the soap_bind, the listen and the wsdd_event_probematches but I don't receive message from Service.


/*MY CLIENT*/

#include "wsdd.nsmap"
#include "soapH.h"
#include "wsddapi.h"

int main () {
    struct soap* soap=soap_new();
    struct soap* serv=soap_new(); //for the listner and the event handler
    int time=100, port=53881;

    if (!soap_valid_socket(soap_bind(soap, NULL, port, 100)))
    { soap_print_fault(soap, stderr);
      exit(0);
    }

    soap->connect_flags=SO_BROADCAST;

    const char * msg_uuid = NULL;
    msg_uuid=soap_wsa_rand_uuid(soap);
    soap_wsdd_Probe(soap, SOAP_WSDD_ADHOC, SOAP_WSDD_TO_TS,"soap.udp://239.255.255.250:3702",msg_uuid, NULL,"dp0:NetworkVideoTransmitter","", NULL);

    soap_wsdd_listen(serv, 2); // listen for messages

    soap_destroy(soap);
    soap_end(soap);
    soap_done(soap);
    return 0;
}

Event Handler in the wsddapi.c I have implemented the wsdd_event_probematches()

void wsdd_event_ProbeMatches(struct soap *soap, unsigned int InstanceId, const char *SequenceId, unsigned int MessageNumber, const char *MessageID, const char *RelatesTo, struct wsdd__ProbeMatchesType *matches){
    printf("MessageID:%s",MessageID);
    printf("%s",matches->ProbeMatch->XAddrs);
}

Solution

  • In order to receive UDP, it is needed to create soap instance with soap_new1(SOAP_IO_UDP)

    The documentation of gSOAP is quite obscure about WS-Discovery plugins and I was confused about soap instance for sending request and soap instance to collect answers.
    In order to received unicast answers of the multicast request it is needed to use the same soap instance :

    int main(int argc, char** argv)
    {
            struct soap* serv = soap_new1(SOAP_IO_UDP);
            if (!soap_valid_socket(soap_bind(serv, NULL, 0, 1000)))
            {
                    soap_print_fault(serv, stderr);
                    exit(1);
            }
            int res = soap_wsdd_Probe(serv, 
                                      SOAP_WSDD_ADHOC, 
                                      SOAP_WSDD_TO_TS,
                                      "soap.udp://239.255.255.250:3702",
                                      soap_wsa_rand_uuid(serv), 
                                      NULL, 
                                      NULL, 
                                      NULL, 
                                      "");
            if (res != SOAP_OK)
            {
                    soap_print_fault(serv, stderr);
                    exit(1);
            }
            soap_wsdd_listen(serv, 1);
            soap_destroy(serv);
            soap_end(serv);
            soap_done(serv);
            return 0;
    }