The problem with UpnpSendAction function

Hao Hu
2011-09-14
2012-12-14
  • Hao Hu
    Hao Hu
    2011-09-14

    Hi all,
    I want to send a synchronized action, so I use UpnpSendAction function to do it. But I got a little confused about the 4th parameter which needs a IXML_Document** pointer. Should I use ixmlDocument_createDocument() to create a blank document and pass it to function? If I do it like this, it will cause memory leak. How should I use the UpnpSendAction() function? Thanks very much for any help!!

     
  • Hi,

    In file Upnp.h, you have this:

    /*!
    * \brief Sends a message to change a state variable in a service.
    *
    * This is a synchronous call that does not return until the action is complete.
    *
    * Note that a positive return value indicates a SOAP-protocol error code.
    * In this case,  the error description can be retrieved from \b RespNode.
    * A negative return value indicates an SDK error.
    *
    * \return An integer representing one of the following:
    *     \li \c UPNP_E_SUCCESS: The operation completed successfully.
    *     \li \c UPNP_E_INVALID_HANDLE: The handle is not a valid control
    *             point handle.
    *     \li \c UPNP_E_INVALID_URL: \b ActionUrl is not a valid URL.
    *     \li \c UPNP_E_INVALID_ACTION: This action is not valid.
    *     \li \c UPNP_E_INVALID_DEVICE: \b DevUDN is not a
    *             valid device.
    *     \li \c UPNP_E_INVALID_PARAM: \b ServiceType, \b Action,
    *             \b ActionUrl, or
    *             \b RespNode is not a valid pointer.
    *     \li \c UPNP_E_OUTOF_MEMORY: Insufficient resources exist to
    *             complete this operation.
    */
    EXPORT_SPEC int UpnpSendAction(
    /*!  The handle of the control point sending the action. */
    UpnpClient_Handle Hnd,
    /*!  The action URL of the service. */
    const char *ActionURL,
    /*!  The type of the service. */
    const char *ServiceType,
    /*!  This parameter is ignored and must be \c NULL. */
    const char *DevUDN,
    /*!  The DOM document for the action. */
    IXML_Document *Action,
    /*!  The DOM document for the response to the action. The SDK allocates
    * this document and the caller needs to free it. */
    IXML_Document **RespNode);

    So, the last line clearly states that you should pass a pointer to a pointer that will be allocated by the library and must be freed by the user. The original value of the pointer can be anything, including garbage, since this value will not be used by the library. But it should definitely not be the last copy of a valid pointer, otherwise memory will surely leak.

    Regards,
    Marcelo.

     
  • Hao Hu
    Hao Hu
    2011-09-14

    Hi Marcelo,
    Thanks very much for you reply. I have read the header file, but I am not so clear how to create the RespNode parameter with help of libupnp. I read through the header files of ixml, I can only find ixmlDocument_createDocument() function.
    Regards,
    Hao

     
  • Hao Hu
    Hao Hu
    2011-09-14

    Hi Marcelo,
    Thanks again for you patient. I have a beginner question.
    Why the original value of the pointer cannot be NULL?
    Point to anything or some garbage is kind of potential risk?

     
  • Hi Hao,

    The original value of the pointer CAN be NULL. It can have any value, since the library does not care. The library needs a place to store the new pointer. You should do something like this:

    int retval;
    UpnpClient_Handle Hnd;
    const char *ActionURL;
    const char *ServiceType;
    IXML_Document *Action;
    /* RespNode is a pointer to an IXML_Document, see the single asterisk. 
     * There is no need to initialize this variable. */
    IXML_Document *RespNode;
    ... other calls to initialize stuff ...
    retval = UpnpSendAction(Hnd, ActionURL, ServiceType, NULL, Action, &RespNode);
    ... take a look at RespNode to see what actually happened ...
    

    Regards,
    Marcelo.

     
  • Hao Hu
    Hao Hu
    2011-09-14

    Thanks again again for your patient and reply :).
    As you said I CAN set NULL to the RespNode, but in upnpapi.c file,
       if( ServiceType == NULL || Action == NULL || RespNodePtr == NULL
            || DevUDN_const != NULL ) {
            return UPNP_E_INVALID_PARAM;
        }
    If I set RespNode as NULL, it will return invalid parameter error.
    Cheers,
    Hao

     
  • Hao Hu
    Hao Hu
    2011-09-14

    Hi Marcelo,
    Sorry It is my mistake, it is double **. Thanks for your hints and solution.
    Best wishes,
    Hao