开发者

Windows COM action invoke on UPNP

I'm working with COM UPnP. I'm trying to send SetAVTransportURI action to urn:upnp-org:serviceId:AVTransport. SetAVTransportURI requires 3 params:

  • InstanceID: 0
  • CurrentURI: http://192.168.0.8/test/1.mp3
  • CurrentURIMetaData: empty string

after invoking action I'm receiving Failed to invoke action...

here is my code:

HRESULT ExtractServices(IUPnPDevice * pDevice)
{
    BSTR bstrServiceName = SysAllocString(L"urn:upnp-org:serviceId:AVTransport");

    if(NULL == bstrServiceName)
    {
        return E_OUTOFMEMORY;
    }


    IUPnPServices * pServices = NULL;
    HRESULT hr = pDevice->get_Services(&pServices);

    if(SUCCEEDED(hr))
    {
        IUPnPService * pAppService = NULL;
        hr = pServices->get_Item(bstrServiceName, &pAppService);

        if(SUCCEEDED(hr))
        {
            printf("got AVTransport\r\n");

            VARIANT vInArg;
            VARIANT vRetVal;
            VARIANT vOutVal;

            VariantInit(&vInArg);
            VariantInit(&vRetVal);
            VariantInit(&vOutVal);

            SAFEARRAYBOUND bounds[1];
            bounds[0].lLbound = 0;
            bounds[0].cElements = 3;    

            SAFEARRAY* saInArgs = SafeArrayCreate(VT_VARIANT,3,bounds);
            LONG lArg;

            lArg = 0;
            SafeArrayPutElement(saInArgs,&lArg,SysAllocString(L"0"));

            lArg = 1;
            SafeArrayPutElement(saInArgs,&lArg,SysAllocString(L"http://192.168.0.8/test/1.mp3"));

            lArg = 2;
            SafeArrayPutElement(saInArgs,&lArg,SysAllocString(L"NOT_IMPLEMENTED"));

            vInArg.pparray = &saInArgs;
            vInArg.vt = VT_VARIANT | VT_ARRAY | VT_BYREF;

            //VARIANT varInArgs;
            //VariantInit(&varInArgs);
            //varInArgs.vt = VT_VARIANT | VT_ARRAY;
            //V_ARRAY(&varInArgs) = saInArgs;

            hr = pAppService->InvokeAction(SysAllocString(L"SetAVTransportURI"),vInArg,&vRetVal,&vOutVal);

            if(SUCCEEDED(hr))
            {
                printf("InvokeAction success");
            }
            else if(hr == UPNP_E_ACTION_REQUEST_FAILED)
            {
                printf("The device had an internal error; the request could not be executed.");
            }
            else if(hr == UPNP_E_DEVICE_ERROR)
            {
                printf("An unknown error occurred.");
            }
            else if(hr == UPNP_E_DEVICE_TIMEOUT)
            {
                printf("The device has not responded within the 30 second time-out period.");
            }
            else if(hr == UPNP_E_ERROR_PROCESSING_RESPONSE)
            {
                printf("The device has sent a response that cannot be processed; for example, the response was corrupted\n");
            }
            else if(hr == UPNP_E_INVALID_ACTION)
            {
                printf("The action is not supported by the device\n");
            }
            else if(hr == UPNP_E_INVALID_ARGUMENTS)
            {
                printf("One or more of the arguments passed in vInActionArgs is invalid\n");
            }
            else if(hr == UPNP_E_PROTOCOL_ERROR)
            {
                printf("An error occurred at the UPnP control-protocol level\n");
            }
            else if(hr == UPNP_E_TRANSPORT_ERROR)
            {
                printf("An HTTP error occurred. Use the IUPnPService::LastTransportStatus property to obtain the actual HTTP status code\n");
            }
            else
            {
                printf("Failed to invoke action...\n");
            }


            pAppService->Release();
        }

        pServices->Release();
    }
    SysFreeString(bstrServiceName);
    return hr;
}

I think the problem is with passing params in VARIANT section, can anyone give me a hand with that?


I have changed my code:

HRESULT ExtractServices(IUPnPDevice * pDevice)
{
    BSTR bstrServiceName = SysAllocString(L"urn:upnp-org:serviceId:AVTransport");

    if(NULL == bstrServiceName)
    {
        return E_OUTOFMEMORY;
    }


    IUPnPServices * pServices = NULL;
    HRESULT hr = pDevice->get_Services(&pServices);

    if(SUCCEEDED(hr))
    {
        IUPnPService * pAppService = NULL;
        hr = pServices->get_Item(bstrServiceName, &pAppService);

        if(SUCCEEDED(hr))
        {
            printf("got AVTransport\r\n");

            VARIANT vInArg;
            VARIANT vRetVal;
            VARIANT vOutVal;

            VariantInit(&vInArg);
            VariantInit(&vRetVal);
            VariantInit(&vOutVal);

            SAFEARRAYBOUND bounds[1];
            bounds[0].lLbound = 0;
            bounds[0].cElements = 2;    

            SAFEARRAY* saInArgs = SafeArrayCreate(VT_VARIANT,1,bounds);
            VARIANT vParam;
            LONG lParam[1];

            VariantInit(&vParam);
            vParam.vt = VT_BSTR;
            V_BSTR(&vParam) = SysAllocString(L"http://192.168.0.8/test/1.mp3");
            lParam[0] = 0;
            SafeArrayPutElement(saInArgs,lParam,&vParam);
            VariantClear(&vParam);

            VariantInit(&vParam);
            vParam.vt = VT_BSTR;
            V_BSTR(&vParam) = SysAllocString(L"");
            lParam[0] = 1;
            SafeArrayPutElement(saInArgs,lParam,&vParam);
            VariantClear(&vParam);

            vInArg.vt = VT_ARRAY | VT_VARIANT;
            V_ARRAY(&vInArg) = saInArgs;


            //VARIANT varInArgs;
            //VariantInit(&varInArgs);
            //varInArgs.vt = VT_VARIANT | VT_ARRAY | VT_BSTR;
            //V_ARRAY(&varInArgs) = saInArgs;

            hr = pAppService->InvokeAction(SysAllocString(L"SetAVTransportURI"),vInArg,&vRetVal,&vOutVal);

            if(SUCCEEDED(hr))
            {
                printf("InvokeAction success");
            }
            else if(hr == UPNP_E_ACTION_REQUEST_FAILED)
            {
                printf("The device had an internal error; the request could not be executed.");
            }
            else if(hr == UPNP_E_DEVICE_ERROR)
            {
                printf("An unknown error occurred.");
            }
            else if(hr == UPNP_E_DEVICE_TIMEOUT)
            {
                printf("The device has not responded within the 30 second time-out period.");
            }
            else if(hr == UPNP_E_ERROR_PROCESSING_RESPONSE)
            {
                printf("The device has sent a response that cannot be processed; for example, the response was corrupted\n");
            }
            else if(hr == UPNP_E_INVALID_ACTION)
            {
                printf("The action is not supported by the device\n");
            }
            else if(hr == UPNP_E_INVALID_ARGUMENTS)
            {
                printf("One or more of the arguments passed in vInActionArgs is invalid\n");
            }
            else if(hr == UPNP_E_PROTOCOL_ERROR)
            {
                printf("An error occurred at the UPnP control-protocol level\n");
            }
            else if(hr == UPNP_E_TRANSPORT_ERROR)
            {
                printf("An HTTP error occurred. Use the IUPnPService::LastTransportStatus property to obtain the actual HTTP status code\n");
            }
            else
            {
                printf("Failed to invoke action... %d\n",hr);
            }


            pAppService->Release();
        }

        pServices->Release();
    }
    SysFreeStr开发者_如何学Pythoning(bstrServiceName);
    return hr;
}

and I still have problem with the args: One or more of the arguments passed in vInActionArgs is invalid...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜