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...
精彩评论