Windows COM действие вызывает на UPNP - PullRequest
2 голосов
/ 21 сентября 2011

Я работаю с COM UPnP. Я пытаюсь отправить действие SetAVTransportURI в urn: upnp-org: serviceId: AVTransport. Для SetAVTransportURI требуется 3 параметра:

  • InstanceID: 0
  • CurrentURI: http://192.168.0.8/test/1.mp3
  • CurrentURIMetaData: пустая строка

после вызова действия я получаю Не удалось вызвать действие ...

вот мой код:

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;
}

Я думаю, что проблема в передаче параметров в разделе VARIANT, кто-нибудь может мне помочь с этим?


Я изменил свой код:

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();
    }
    SysFreeString(bstrServiceName);
    return hr;
}

и у меня все еще есть проблема с аргументами: один или несколько аргументов, переданных в vInActionArgs, недействительны ...

...