3

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);
}
Flexo
  • 87,323
  • 22
  • 191
  • 272
Luca84
  • 63
  • 1
  • 4

1 Answers1

1

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;
}
mpromonet
  • 11,326
  • 43
  • 62
  • 91
  • I've tried your code but not working...if you debug you can see that the event handler of probmatches in wsddapi.c is call only if you use SOAP_WSDD_MANAGED and not SOAP_WSDD_ADHOC...it's more strange. and if you use a loop like for(;;) in wsddapi.c when is call the event handler in soap_wsdd_Probe() you can see all the probematches from the Target Service. It's more strange an i think is not the correct way. – Luca84 Nov 28 '14 at 09:59
  • @Luca84 in SOAP_WSDD_ADHOC mode, wsdd_event_ProbeMatches handler is called processing the ProbeMatches message (from __wsdd__ProbeMatches). You can find my tries from github https://github.com/mpromonet/ws-discovery/tree/master/gsoap. I run it successfully with gSOAP 2.8.7 & gSOAP 2.8.17. – mpromonet Nov 28 '14 at 19:09
  • Hi @mpromonet, I am using your example in gitHub. I used prob normally. But when compile server.cpp it gives error. error: cannot convert 'ip_mreq*' to 'const char*' for argument '4' to 'int setsockopt(SOCKET, int, int, const char*, int)' if (setsockopt(serv->master, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))<0)' How can i solve it? – Sattar Hummatli Nov 12 '15 at 10:37
  • @SettarHummetli : this is far from the question that deals with probe. You should consider to ask a question extracting a minimal example that brings the problem. Nevertheless I guess you need a cast like `setsockopt(serv->master, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast)` – mpromonet Nov 12 '15 at 20:13