Commit f85ed299 authored by Larry Sachs's avatar Larry Sachs Committed by Rick Bell

Add UpnpBridgeDevice

The Upnp Bridge Device (oic.d.bridge) will be created when the
upnp plugin starts and removed when the plugin stops.

The bridge device's links will be the href of the upnp virtual
resources.

Change-Id: I8257b331f0175715f4874eef01a4024fbc4d31a9
Signed-off-by: Larry Sachs's avatarLarry Sachs <larry.j.sachs@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18849Reviewed-by: George Nash's avatarGeorge Nash <george.nash@intel.com>
Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: default avatarRick Bell <richard.s.bell@intel.com>
parent f0d7677d
......@@ -96,6 +96,7 @@ upnp_env.PrependUnique(LIBS = ['m',
######################################################################
upnp_src = [
'upnp_plugin.cpp',
'UpnpBridgeDevice.cpp',
'UpnpConnector.cpp',
'UpnpDevice.cpp',
'UpnpDimmingService.cpp',
......
//******************************************************************
//
// Copyright 2017 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 <iostream>
#include <ocrandom.h>
#include <ocstack.h>
#include <octypes.h>
#include <oic_string.h>
#include <oic_malloc.h>
#include <pluginServer.h>
#include <ConcurrentIotivityUtils.h>
#include "UpnpBridgeDevice.h"
#include "UpnpException.h"
#include "UpnpInternal.h"
using namespace std;
using namespace OC::Bridging;
static const string MODULE = "UpnpBridgeDevice";
static const string BRIDGE_RESOURCE_TYPE = "oic.d.bridge";
static string s_bridgeUri = "/upnp-bridge/0";
static vector<_link> s_links;
UpnpBridgeDevice::UpnpBridgeDevice()
{
uint8_t resourceProperties = (OC_OBSERVABLE | OC_DISCOVERABLE);
// Generate a UUID for the Protocol Independent ID
uint8_t uuid[UUID_SIZE] = {0};
if (!OCGenerateUuid(uuid))
{
// TODO: throw error on failure ?
DEBUG_PRINT("Generate UUID for Upnp Bridge Device failed");
}
char uuidString[UUID_STRING_SIZE] = {0};
if (!OCConvertUuidToString(uuid, uuidString)) {
// TODO: throw error on failure ?
DEBUG_PRINT("Convert UUID to string for Upnp Bridge Device failed");
}
s_bridgeUri = "/upnp-bridge/" + string(uuidString);
OCStackResult result = ConcurrentIotivityUtils::queueCreateResource(s_bridgeUri,
BRIDGE_RESOURCE_TYPE, OC_RSRVD_INTERFACE_ACTUATOR, entityHandler,
(void *) 0, resourceProperties);
DEBUG_PRINT("Plugin start queueCreateResource() result = " << result);
}
UpnpBridgeDevice::~UpnpBridgeDevice()
{
OCStackResult result = OC::Bridging::ConcurrentIotivityUtils::queueDeleteResource(s_bridgeUri);
DEBUG_PRINT("Plugin stop queueDeleteResource() result = " << result);
}
void UpnpBridgeDevice::addResource(UpnpResource::Ptr pResource)
{
_link singleLink;
singleLink.href = pResource->m_uri;
singleLink.rel = "contains";
singleLink.rt = pResource->getResourceType();
s_links.push_back(singleLink);
}
// Entity handler
OCEntityHandlerResult UpnpBridgeDevice::entityHandler(OCEntityHandlerFlag flag,
OCEntityHandlerRequest *entityHandlerRequest, void *callback)
{
uintptr_t callbackParamResourceType = (uintptr_t)callback;
(void)callbackParamResourceType;
return handleEntityHandlerRequests(flag, entityHandlerRequest, BRIDGE_RESOURCE_TYPE);
}
OCEntityHandlerResult UpnpBridgeDevice::handleEntityHandlerRequests(OCEntityHandlerFlag,
OCEntityHandlerRequest *entityHandlerRequest, string resourceType)
{
OCEntityHandlerResult ehResult = OC_EH_ERROR;
OCRepPayload *responsePayload = NULL;
OCRepPayload *payload = OCRepPayloadCreate();
try
{
if ((entityHandlerRequest == NULL))
{
throw "Entity handler received a null entity request context" ;
}
string uri = OCGetResourceUri(entityHandlerRequest->resource);
DEBUG_PRINT("URI from resource " << uri);
char *interfaceQuery = NULL;
char *resourceTypeQuery = NULL;
char *dupQuery = OICStrdup(entityHandlerRequest->query);
if (dupQuery)
{
MPMExtractFiltersFromQuery(dupQuery, &interfaceQuery, &resourceTypeQuery);
}
switch (entityHandlerRequest->method)
{
case OC_REST_GET:
DEBUG_PRINT(" GET Request for: " << uri);
ehResult = processGetRequest(uri, resourceType, payload);
break;
default:
DEBUG_PRINT("UnSupported Method [" << entityHandlerRequest->method << "] Received");
ConcurrentIotivityUtils::respondToRequestWithError(entityHandlerRequest, "Unsupported Method", OC_EH_METHOD_NOT_ALLOWED);
return OC_EH_OK;
}
responsePayload = getCommonPayload(uri.c_str(), interfaceQuery, resourceType, payload);
ConcurrentIotivityUtils::respondToRequest(entityHandlerRequest, responsePayload, ehResult);
OICFree(dupQuery);
}
catch (const char *errorMessage)
{
DEBUG_PRINT("Error - " << errorMessage);
ConcurrentIotivityUtils::respondToRequestWithError(entityHandlerRequest, errorMessage, OC_EH_ERROR);
ehResult = OC_EH_OK;
}
OCRepPayloadDestroy(responsePayload);
return ehResult;
}
OCEntityHandlerResult UpnpBridgeDevice::processGetRequest(string uri, string resType, OCRepPayload *payload)
{
if (payload == NULL)
{
throw "payload is null";
}
if (BRIDGE_RESOURCE_TYPE == resType)
{
bool secureMode = false;
if (!OCRepPayloadSetPropBool(payload, "secureMode", secureMode))
{
throw "Failed to set 'secureMode' in payload";
}
DEBUG_PRINT(uri << " -- secureMode: " << (secureMode ? "true" : "false"));
if (!s_links.empty())
{
DEBUG_PRINT("Setting links");
const OCRepPayload *links[s_links.size()];
size_t dimensions[MAX_REP_ARRAY_DEPTH] = {s_links.size(), 0, 0};
for (unsigned int i = 0; i < s_links.size(); ++i) {
DEBUG_PRINT("link[" << i << "]");
DEBUG_PRINT("\thref=" << s_links[i].href);
DEBUG_PRINT("\trel=" << s_links[i].rel);
DEBUG_PRINT("\trt=" << s_links[i].rt);
OCRepPayload *linkPayload = OCRepPayloadCreate();
OCRepPayloadSetPropString(linkPayload, "href", s_links[i].href.c_str());
OCRepPayloadSetPropString(linkPayload, "rel", s_links[i].rel.c_str());
OCRepPayloadSetPropString(linkPayload, "rt", s_links[i].rt.c_str());
links[i] = linkPayload;
}
OCRepPayloadSetPropObjectArray(payload, "links", links, dimensions);
}
}
else
{
throw "Failed due to unknown resource type";
}
return OC_EH_OK;
}
OCRepPayload* UpnpBridgeDevice::getCommonPayload(const char *uri, char *interfaceQuery, string resourceType,
OCRepPayload *payload)
{
if (!OCRepPayloadSetUri(payload, uri))
{
throw "Failed to set uri in the payload";
}
if (!OCRepPayloadAddResourceType(payload, resourceType.c_str()))
{
throw "Failed to set resource type in the payload" ;
}
DEBUG_PRINT("Checking against if: " << interfaceQuery);
// If the interface filter is explicitly oic.if.baseline, include all properties.
if (interfaceQuery && string(interfaceQuery) == string(OC_RSRVD_INTERFACE_DEFAULT))
{
if (!OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_ACTUATOR))
{
throw "Failed to set actuator interface";
}
if (!OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT))
{
throw "Failed to set baseline interface" ;
}
}
return payload;
}
//******************************************************************
//
// Copyright 2017 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_BRIDGE_DEVICE_H_
#define UPNP_BRIDGE_DEVICE_H_
#include "UpnpResource.h"
class UpnpBridgeDevice
{
public:
UpnpBridgeDevice();
~UpnpBridgeDevice();
static OCEntityHandlerResult entityHandler(OCEntityHandlerFlag flag,
OCEntityHandlerRequest *entityHandlerRequest, void *callback);
static OCEntityHandlerResult handleEntityHandlerRequests(OCEntityHandlerFlag flag,
OCEntityHandlerRequest *entityHandlerRequest, std::string resourceType);
static OCEntityHandlerResult processGetRequest(std::string uri,
std::string resType, OCRepPayload *payload);
static OCRepPayload* getCommonPayload(const char *uri, char *interfaceQuery,
std::string resourceType, OCRepPayload *payload);
void addResource(UpnpResource::Ptr resource);
};
#endif
......@@ -30,6 +30,7 @@
#include "logger.h"
#include "UpnpConnector.h"
#include "UpnpResource.h"
#include "UpnpBridgeDevice.h"
#define TAG "UPNP_PLUGIN"
static std::string MODULE = "UPNP_PLUGIN MODULE";
......@@ -45,21 +46,22 @@ FILE *sec_file(const char *, const char *mode)
}
static UpnpConnector *s_upnpConnector;
static UpnpBridgeDevice *s_bridge;
std::vector< UpnpResource::Ptr > m_vecResources;
int connectorDiscoveryCb(UpnpResource::Ptr pUpnpResource)
{
int result = 0;
DEBUG_PRINT("UpnpResource URI " << pUpnpResource->m_uri);
//result = m_pResourceContainer->registerResource(pUpnpResource);
if (result == 0)
m_vecResources.push_back(pUpnpResource);
if (s_bridge != nullptr)
{
m_vecResources.push_back(pUpnpResource);
} else {
ERROR_PRINT(result << " Failed to register resource: " << pUpnpResource->m_uri);
s_bridge->addResource(pUpnpResource);
}
else {
ERROR_PRINT("Failed to add resource: " << pUpnpResource->m_uri);
}
return result;
return 0;
}
extern "C" DLL_PUBLIC MPMResult pluginCreate(MPMPluginCtx **plugin_specific_ctx)
......@@ -89,6 +91,8 @@ extern "C" DLL_PUBLIC MPMResult pluginStart(MPMPluginCtx *ctx)
ctx->stay_in_process_loop = true;
OIC_LOG(INFO, TAG, "Plugin start called!");
s_bridge = new UpnpBridgeDevice();
UpnpConnector::DiscoveryCallback discoveryCb = std::bind(&connectorDiscoveryCb, std::placeholders::_1);
//UpnpConnector::LostCallback lostCb = std::bind(&UpnpBundleActivator::connectorLostCb, this, std::placeholders::_1);
......@@ -166,6 +170,8 @@ extern "C" DLL_PUBLIC MPMResult pluginStop(MPMPluginCtx *)
}
delete s_upnpConnector;
delete s_bridge;
return MPM_RESULT_OK;
}
......
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