Commit 8b407ead authored by Larry Sachs's avatar Larry Sachs

Add support for Media Control and Audio Resources

Change-Id: I35689204a03670ab371d903323e816f19525c32e
Signed-off-by: Larry Sachs's avatarLarry Sachs <larry.j.sachs@intel.com>
parent eecbba1d
Pipeline #37 failed with stages
in 14 seconds
......@@ -57,6 +57,8 @@ upnp_iot_lite_bridge_cpp = ['UpnpBridgeIotLite.cpp',
'UpnpService.cpp',
'UpnpDimmingService.cpp',
'UpnpPowerSwitchService.cpp',
'UpnpAvTransportService.cpp',
'UpnpRenderingControlService.cpp',
'UpnpException.cpp']
upnp_iot_lite_bridge_obj = env_upnp_iot_lite_bridge.Object(upnp_iot_lite_bridge_cpp)
......
This diff is collapsed.
//******************************************************************
//
// Copyright 2018 Intel Corporation All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef UPNP_AV_TRANSPORT_SERVICE_H_
#define UPNP_AV_TRANSPORT_SERVICE_H_
#include <string>
#include <map>
#include <gupnp.h>
#include "UpnpResource.h"
#include "UpnpInternal.h"
#include "UpnpService.h"
using namespace std;
class UpnpAvTransport: public UpnpService
{
public:
UpnpAvTransport(GUPnPServiceInfo *serviceInfo,
UpnpRequestState *requestState):
UpnpService(serviceInfo, UPNP_OIC_TYPE_MEDIA_CONTROL, requestState)
{
}
static void processGetRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data);
static void processPostRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data);
static void processPutRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data);
private:
static void processGetRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data, oc_status_t return_status);
};
#endif // UPNP_AV_TRANSPORT_SERVICE_H_
......@@ -21,7 +21,7 @@
#include "UpnpConnector.h"
#define OC_SERVER
#define OC_DYNAMIC_ALLOCATION
#include <oc_api.h>
#include <pthread.h>
......
......@@ -29,6 +29,7 @@
#include <boost/regex.hpp>
#define OC_SERVER
#define OC_DYNAMIC_ALLOCATION
#include <oc_core_res.h>
#include <UpnpConstants.h>
......@@ -302,7 +303,8 @@ void UpnpConnector::onDeviceProxyAvailable(GUPnPControlPoint *controlPoint,
if (pUpnpResource != nullptr && !pUpnpResource->isRegistered())
{
if (pUpnpResource->getResourceType() == UPNP_OIC_TYPE_DEVICE_LIGHT)
if (pUpnpResource->getResourceType() == UPNP_OIC_TYPE_DEVICE_LIGHT ||
pUpnpResource->getResourceType() == UPNP_OIC_TYPE_DEVICE_AV_PLAYER)
{
int ret = oc_add_device("/oic/d", pUpnpResource->getResourceType().c_str(),
pUpnpResource->getName().c_str(), "ocf.1.0.0", "ocf.res.1.0.0,ocf.sh.1.0.0",
......@@ -312,7 +314,7 @@ void UpnpConnector::onDeviceProxyAvailable(GUPnPControlPoint *controlPoint,
{
s_deviceIndexLookup[pUpnpResource->getUdn()] = ++s_deviceIndex;
pUpnpResource->setRegistered(true);
DEBUG_PRINT("Added light device " << pUpnpResource->getName());
DEBUG_PRINT("Added " << pUpnpResource->getResourceType() << " device " << pUpnpResource->getName());
// for (std::map< string, int >::iterator iter = s_deviceIndexLookup.begin(); iter != s_deviceIndexLookup.end(); ++iter)
// std::cout << iter->first << " => " << iter->second << '\n';
......@@ -321,7 +323,7 @@ void UpnpConnector::onDeviceProxyAvailable(GUPnPControlPoint *controlPoint,
{
pUpnpResource->setRegistered(false);
unregisterDeviceResource(udn);
DEBUG_PRINT("Failed to add light device " << pUpnpResource->getName());
DEBUG_PRINT("Failed to add " << pUpnpResource->getResourceType() << " device " << pUpnpResource->getName());
return;
}
}
......
......@@ -27,6 +27,7 @@
#include <gupnp-service-proxy.h>
#define OC_SERVER
#define OC_DYNAMIC_ALLOCATION
#include <oc_api.h>
using namespace std;
......
......@@ -53,7 +53,7 @@ void UpnpDimming::processGetRequest(oc_request_t *request, oc_interface_mask_t i
oc_rep_start_root_object();
oc_process_baseline_interface(request->resource);
DEBUG_PRINT("oc_rep_set_int " << brightnessLevelName << " " << brightnessLevelValue);
DEBUG_PRINT("oc_rep_set_int " << brightnessLevelName << ": " << brightnessLevelValue);
oc_rep_set_int(root, brightness, brightnessLevelValue);
oc_rep_end_root_object();
oc_send_response(request, OC_STATUS_OK);
......@@ -90,7 +90,7 @@ void UpnpDimming::processPostRequest(oc_request_t *request, oc_interface_mask_t
GError *error = NULL;
if (! gupnp_service_proxy_send_action(proxy, "SetLoadLevelTarget", &error,
// IN args
"newLoadlevelTarget", G_TYPE_BOOLEAN, brightnessLevelValue,
"newLoadlevelTarget", G_TYPE_UINT, brightnessLevelValue,
NULL,
// OUT args (none)
NULL))
......
......@@ -28,6 +28,8 @@
#include <string>
#include <vector>
#define OC_SERVER
#define OC_DYNAMIC_ALLOCATION
#include <oc_api.h>
#include <UpnpConstants.h>
......@@ -56,6 +58,7 @@ static std::map<std::string, std::string > UpnpSearchPatternMap =
{UPNP_OIC_TYPE_BRIGHTNESS, UPNP_PREFIX_SERVICE + ":.*(?:[Dd]imming).*"},
{UPNP_OIC_TYPE_POWER_SWITCH, UPNP_PREFIX_SERVICE + ":.*(?:[Ss]witch[Pp]ower).*"},
// Media Control
{UPNP_OIC_TYPE_DEVICE_AV_PLAYER, UPNP_PREFIX_DEVICE + ":.*(?:[Mm]edia[Rr]enderer).*"},
{UPNP_OIC_TYPE_AUDIO, UPNP_PREFIX_SERVICE + ":.*(?:[Rr]endering[Cc]ontrol).*"},
{UPNP_OIC_TYPE_MEDIA_CONTROL, UPNP_PREFIX_SERVICE + ":.*(?:[Aa][Vv][Tt]ransport).*"}
};
......@@ -71,11 +74,12 @@ static std::map<std::string, std::string > UpnpInterfaceMap =
{UPNP_OIC_TYPE_POWER_SWITCH, "oic.if.a"},
{UPNP_OIC_TYPE_BRIGHTNESS, "oic.if.a"},
// Media Control
{UPNP_OIC_TYPE_DEVICE_MEDIA_RENDERER, "oic.if.baseline"},
{UPNP_OIC_TYPE_DEVICE_MEDIA_SERVER, "oic.if.baseline"},
{UPNP_OIC_TYPE_DEVICE_AV_PLAYER, "oic.if.baseline"},
{UPNP_OIC_TYPE_AUDIO, "oic.if.a"},
{UPNP_OIC_TYPE_MEDIA_CONTROL, "oic.if.a"}
};
// URI prexfix map
// URI prefix map
// TODO and TBD
static std::map<std::string, std::string > UpnpUriPrefixMap =
{
......@@ -83,8 +87,9 @@ static std::map<std::string, std::string > UpnpUriPrefixMap =
{UPNP_OIC_TYPE_BRIGHTNESS, UPNP_OIC_URI_PREFIX_BRIGHTNESS},
{UPNP_OIC_TYPE_POWER_SWITCH, UPNP_OIC_URI_PREFIX_POWER_SWITCH},
{UPNP_OIC_TYPE_AV_TRANSPORT, UPNP_OIC_URI_PREFIX_AV_TRANSPORT},
{UPNP_OIC_TYPE_RENDERING_CONTROL, UPNP_OIC_URI_PREFIX_RENDERING_CONTROL}
{UPNP_OIC_TYPE_DEVICE_AV_PLAYER, UPNP_OIC_URI_PREFIX_MEDIA_RENDERER},
{UPNP_OIC_TYPE_AUDIO, UPNP_OIC_URI_PREFIX_AUDIO},
{UPNP_OIC_TYPE_MEDIA_CONTROL, UPNP_OIC_URI_PREFIX_MEDIA_CONTROL}
};
#define ERROR_PRINT(x) do { std::cerr << MODULE << ":" << __func__ << "(): ERROR: " << x << std::endl; } while (0)
......
......@@ -25,6 +25,8 @@
#include "UpnpDimmingService.h"
#include "UpnpPowerSwitchService.h"
#include "UpnpAvTransportService.h"
#include "UpnpRenderingControlService.h"
using namespace std;
......@@ -367,6 +369,14 @@ std::shared_ptr<UpnpService> UpnpManager::generateService(GUPnPServiceInfo *ser
{
return (std::make_shared < UpnpDimming > (serviceInfo, requestState));
}
else if (resourceType == UPNP_OIC_TYPE_AUDIO)
{
return (std::make_shared < UpnpRenderingControl > (serviceInfo, requestState));
}
else if (resourceType == UPNP_OIC_TYPE_MEDIA_CONTROL)
{
return (std::make_shared < UpnpAvTransport > (serviceInfo, requestState));
}
else
{
//throw an exception
......
......@@ -53,7 +53,7 @@ void UpnpPowerSwitch::processGetRequest(oc_request_t *request, oc_interface_mask
oc_rep_start_root_object();
oc_process_baseline_interface(request->resource);
DEBUG_PRINT("oc_rep_set_boolean " << powerSwitchStateName << " " << powerSwitchStateValue);
DEBUG_PRINT("oc_rep_set_boolean " << powerSwitchStateName << ": " << powerSwitchStateValue);
oc_rep_set_boolean(root, value, powerSwitchStateValue);
oc_rep_end_root_object();
oc_send_response(request, OC_STATUS_OK);
......
//******************************************************************
//
// Copyright 2018 Intel Corporation All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "UpnpRenderingControlService.h"
static const string MODULE = "UpnpRenderingControlService";
// Rendering Control Service
static const char *mutePropertyName = "mute";
static const char *volumePropertyName = "volume";
static const char *getMuteAction = "GetMute";
static const char *setMuteAction = "SetMute";
static const char *getVolumeAction = "GetVolume";
static const char *setVolumeAction = "SetVolume";
static const char *instanceIdParamName = "InstanceID";
static const char *channelParamName = "Channel";
static const char *currentMuteParamName = "CurrentMute";
static const char *desiredMuteParamName = "DesiredMute";
static const char *currentVolumeParamName = "CurrentVolume";
static const char *desiredVolumeParamName = "DesiredVolume";
static const int defaultInstanceID = 0;
static const char *defaultChannel = "Master";
void UpnpRenderingControl::processGetRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data)
{
DEBUG_PRINT("request->resource->name=" << oc_string(request->resource->name));
GUPnPServiceInfo *serviceInfo = (GUPnPServiceInfo *)user_data;
GUPnPServiceProxy *proxy = GUPNP_SERVICE_PROXY(serviceInfo);
bool muteValue = false;
int volumeValue = 0;
GError *error = NULL;
// get mute
if (! gupnp_service_proxy_send_action(proxy, getMuteAction, &error,
// IN args
instanceIdParamName, G_TYPE_UINT, defaultInstanceID,
channelParamName, G_TYPE_STRING, defaultChannel,
NULL,
// OUT args
currentMuteParamName, G_TYPE_BOOLEAN, &muteValue,
NULL))
{
ERROR_PRINT(getMuteAction << " action failed");
if (error)
{
DEBUG_PRINT("Error message: " << error->message);
g_error_free(error);
}
oc_send_response(request, OC_STATUS_INTERNAL_SERVER_ERROR);
return;
}
oc_rep_start_root_object();
oc_process_baseline_interface(request->resource);
DEBUG_PRINT("oc_rep_set_boolean " << mutePropertyName << ": " << muteValue);
oc_rep_set_boolean(root, mute, muteValue);
// get volume
if (! gupnp_service_proxy_send_action(proxy, getVolumeAction, &error,
// IN args
instanceIdParamName, G_TYPE_UINT, defaultInstanceID,
channelParamName, G_TYPE_STRING, defaultChannel,
NULL,
// OUT args
currentVolumeParamName, G_TYPE_UINT, &volumeValue,
NULL))
{
ERROR_PRINT(getVolumeAction << " action failed");
if (error)
{
DEBUG_PRINT("Error message: " << error->message);
g_error_free(error);
}
oc_send_response(request, OC_STATUS_INTERNAL_SERVER_ERROR);
return;
}
DEBUG_PRINT("oc_rep_set_int " << volumePropertyName << ": " << volumeValue);
oc_rep_set_int(root, volume, volumeValue);
oc_rep_end_root_object();
oc_send_response(request, OC_STATUS_OK);
}
void UpnpRenderingControl::processPostRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data)
{
DEBUG_PRINT("request->resource->name=" << oc_string(request->resource->name));
GUPnPServiceInfo *serviceInfo = (GUPnPServiceInfo *)user_data;
GUPnPServiceProxy *proxy = GUPNP_SERVICE_PROXY(serviceInfo);
bool muteValue = false;
int volumeValue = 0;
oc_rep_t *rep = request->request_payload;
while (rep) {
DEBUG_PRINT("key=" << oc_string(rep->name) << ", rep type=" << rep->type);
char *key = (char *)(rep->name).ptr;
// DEBUG_PRINT("char *key=" << key);
if (strncmp(key, mutePropertyName, (rep->name).size) == 0) {
switch (rep->type)
{
case OC_REP_BOOL:
muteValue = rep->value.boolean;
DEBUG_PRINT("New " << mutePropertyName << ": " << muteValue);
break;
default:
DEBUG_PRINT("Unexpected rep type: " << rep->type);
oc_send_response(request, OC_STATUS_BAD_REQUEST);
return;
}
}
if (strncmp(key, volumePropertyName, (rep->name).size) == 0) {
switch (rep->type)
{
case OC_REP_INT:
volumeValue = rep->value.integer;
DEBUG_PRINT("New " << volumePropertyName << ": " << volumeValue);
break;
default:
DEBUG_PRINT("Unexpected rep type: " << rep->type);
oc_send_response(request, OC_STATUS_BAD_REQUEST);
return;
}
}
rep = rep->next;
}
GError *error = NULL;
// set mute
if (!gupnp_service_proxy_send_action(proxy, setMuteAction, &error,
// IN args
instanceIdParamName, G_TYPE_UINT, defaultInstanceID,
channelParamName, G_TYPE_STRING, defaultChannel,
desiredMuteParamName, G_TYPE_BOOLEAN, muteValue,
NULL,
// OUT args (none)
NULL))
{
ERROR_PRINT(setMuteAction << " action failed");
if (error)
{
DEBUG_PRINT("Error message: " << error->message);
g_error_free(error);
}
oc_send_response(request, OC_STATUS_INTERNAL_SERVER_ERROR);
return;
}
DEBUG_PRINT("Set " << mutePropertyName << ": " << muteValue);
// set volume
if (!gupnp_service_proxy_send_action(proxy, setVolumeAction, &error,
// IN args
instanceIdParamName, G_TYPE_UINT, defaultInstanceID,
channelParamName, G_TYPE_STRING, defaultChannel,
desiredVolumeParamName, G_TYPE_UINT, volumeValue,
NULL,
// OUT args (none)
NULL))
{
ERROR_PRINT(setVolumeAction << " action failed");
if (error)
{
DEBUG_PRINT("Error message: " << error->message);
g_error_free(error);
}
oc_send_response(request, OC_STATUS_INTERNAL_SERVER_ERROR);
return;
}
DEBUG_PRINT("Set " << volumePropertyName << ": " << volumeValue);
oc_send_response(request, OC_STATUS_CHANGED);
}
void UpnpRenderingControl::processPutRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data)
{
return processPostRequest(request, interface, user_data);
}
//******************************************************************
//
// Copyright 2018 Intel Corporation All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef UPNP_RENDERING_CONTROL_H_
#define UPNP_RENDERING_CONTROL_H_
#include <string>
#include <map>
#include <gupnp.h>
#include "UpnpResource.h"
#include "UpnpInternal.h"
#include "UpnpService.h"
using namespace std;
class UpnpRenderingControl: public UpnpService
{
public:
UpnpRenderingControl(GUPnPServiceInfo *serviceInfo, UpnpRequestState *requestState) :
UpnpService(serviceInfo, UPNP_OIC_TYPE_AUDIO, requestState)
{
}
static void processGetRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data);
static void processPostRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data);
static void processPutRequest(oc_request_t *request, oc_interface_mask_t interface, void *user_data);
private:
};
#endif
......@@ -29,6 +29,8 @@
#include "UpnpDimmingService.h"
#include "UpnpPowerSwitchService.h"
#include "UpnpAvTransportService.h"
#include "UpnpRenderingControlService.h"
using namespace std;
......@@ -178,17 +180,25 @@ void UpnpService::processGetRequest(oc_request_t *request, oc_interface_mask_t i
for (int i = 0; i < (int)oc_string_array_get_allocated_size(request->resource->types); i++)
{
// size_t size = oc_string_array_get_item_size(request->resource->types, i);
const char *type = oc_string_array_get_item(request->resource->types, i);
DEBUG_PRINT("request->resource->type[" << i << "]=" << type);
if (string(type) == UPNP_OIC_TYPE_POWER_SWITCH)
{
return UpnpPowerSwitch::processGetRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_BRIGHTNESS)
{
return UpnpDimming::processGetRequest(request, interface, user_data);
}
// size_t size = oc_string_array_get_item_size(request->resource->types, i);
const char *type = oc_string_array_get_item(request->resource->types, i);
DEBUG_PRINT("request->resource->type[" << i << "]=" << type);
if (string(type) == UPNP_OIC_TYPE_POWER_SWITCH)
{
return UpnpPowerSwitch::processGetRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_BRIGHTNESS)
{
return UpnpDimming::processGetRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_AUDIO)
{
return UpnpRenderingControl::processGetRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_MEDIA_CONTROL)
{
return UpnpAvTransport::processGetRequest(request, interface, user_data);
}
}
}
......@@ -217,17 +227,25 @@ void UpnpService::processPostRequest(oc_request_t *request, oc_interface_mask_t
for (int i = 0; i < (int)oc_string_array_get_allocated_size(request->resource->types); i++)
{
// size_t size = oc_string_array_get_item_size(request->resource->types, i);
const char *type = oc_string_array_get_item(request->resource->types, i);
DEBUG_PRINT("request->resource->type[" << i << "]=" << type);
if (string(type) == UPNP_OIC_TYPE_POWER_SWITCH)
{
return UpnpPowerSwitch::processPostRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_BRIGHTNESS)
{
return UpnpDimming::processPostRequest(request, interface, user_data);
}
// size_t size = oc_string_array_get_item_size(request->resource->types, i);
const char *type = oc_string_array_get_item(request->resource->types, i);
DEBUG_PRINT("request->resource->type[" << i << "]=" << type);
if (string(type) == UPNP_OIC_TYPE_POWER_SWITCH)
{
return UpnpPowerSwitch::processPostRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_BRIGHTNESS)
{
return UpnpDimming::processPostRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_AUDIO)
{
return UpnpRenderingControl::processPostRequest(request, interface, user_data);
}
if (string(type) == UPNP_OIC_TYPE_MEDIA_CONTROL)
{
return UpnpAvTransport::processPostRequest(request, interface, user_data);
}
}
}
......
......@@ -33,6 +33,7 @@ static const std::string UPNP_OIC_TYPE_DEVICE_INET_GATEWAY = "oic.d.inet.
static const std::string UPNP_OIC_TYPE_DEVICE_WAN = "oic.d.wan";
static const std::string UPNP_OIC_TYPE_DEVICE_WAN_CONNECTION = "oic.d.wan.connection";
static const std::string UPNP_OIC_TYPE_DEVICE_LAN = "oic.d.lan";
static const std::string UPNP_OIC_TYPE_DEVICE_AV_PLAYER = "oic.d.avplayer";
static const std::string UPNP_OIC_TYPE_DEVICE_MEDIA_RENDERER = "oic.d.media.renderer";
static const std::string UPNP_OIC_TYPE_DEVICE_MEDIA_SERVER = "oic.d.media.server";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment