Commit f54fbc38 authored by Larry Sachs's avatar Larry Sachs Committed by George Nash

add oic.d.light for UPnP lights

Change-Id: I1847b1a631fb49bcfd6676e0b870623b3d1a9292
Signed-off-by: Larry Sachs's avatarLarry Sachs <larry.j.sachs@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18537Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: George Nash's avatarGeorge Nash <george.nash@intel.com>
parent 91f007e8
......@@ -62,8 +62,9 @@ static map <gulong, GUPnPControlPoint *> s_signalMap;
static bool isRootDiscovery[] = {false, true};
const uint BINARY_SWITCH_CALLBACK = 0;
const uint BRIGHTNESS_CALLBACK = 1;
const uint LIGHT_CALLBACK = 0;
const uint BINARY_SWITCH_CALLBACK = 1;
const uint BRIGHTNESS_CALLBACK = 2;
UpnpConnector::UpnpConnector(DiscoveryCallback discoveryCallback, LostCallback lostCallback)
{
......@@ -277,90 +278,98 @@ void UpnpConnector::onDeviceProxyAvailable(GUPnPControlPoint *controlPoint,
GUPnPDeviceProxy *proxy,
gpointer userData)
{
// GUPnPDeviceInfo *deviceInfo = GUPNP_DEVICE_INFO(proxy);
// UpnpResource::Ptr pUpnpResource;
// const string udn = gupnp_device_info_get_udn(deviceInfo);
// bool isRoot = *(static_cast <bool *> (userData));
//
// DEBUG_PRINT("Device type: " << gupnp_device_info_get_device_type(deviceInfo));
//#ifndef NDEBUG
// char *devModel = gupnp_device_info_get_model_name(deviceInfo);
// if (devModel != NULL)
// {
// DEBUG_PRINT("\tDevice model: " << devModel);
// g_free(devModel);
// }
//
// char *devName = gupnp_device_info_get_friendly_name(deviceInfo);
// if (devName != NULL)
// {
// DEBUG_PRINT("\tFriendly name: " << devName);
// g_free(devName);
// }
//#endif
// DEBUG_PRINT("\tUdn: " << udn);
//
// if (isRoot)
// {
// // Root device
// pUpnpResource = s_manager->processDevice(proxy, deviceInfo, true, &s_requestState);
// }
// else
// {
// pUpnpResource = s_manager->processDevice(proxy, deviceInfo, false, &s_requestState);
// }
//
// if (pUpnpResource != nullptr && !pUpnpResource->isRegistered())
// {
// DEBUG_PRINT("Register device resource: " << pUpnpResource->m_uri);
// if (s_discoveryCallback(pUpnpResource) == 0)
// {
// pUpnpResource->setRegistered(true);
// }
// else
// {
// pUpnpResource->setRegistered(false);
// unregisterDeviceResource(udn);
// return;
// }
//
// // Traverse the service list and register all the services where isReady() returns true.
// // This is done in order to catch all the services that have been seen
// // prior to discovering the hosting device.
// GList *childService = gupnp_device_info_list_services (deviceInfo);
//
// while (childService)
// {
// GUPnPServiceInfo *serviceInfo = GUPNP_SERVICE_INFO (childService->data);
// std::shared_ptr<UpnpResource> pUpnpResourceService = s_manager->findResource(serviceInfo);
// if (pUpnpResourceService == nullptr)
// {
// DEBUG_PRINT("Registering device: Service link is empty!");
// // This could happen if support for the service is not implemented
// }
// else
// {
// DEBUG_PRINT(pUpnpResourceService->m_uri << "ready " << pUpnpResourceService->isReady() <<
// " and registered " << pUpnpResourceService->isRegistered());
// if (pUpnpResourceService->isReady() && !pUpnpResourceService->isRegistered())
// {
// DEBUG_PRINT("Register resource for previously discovered child service: " <<
// pUpnpResourceService->m_uri);
// s_discoveryCallback(pUpnpResourceService);
// pUpnpResourceService->setRegistered(true);
//
// // Subscribe to notifications
// // Important!!! UpnpService object associated with this info/proxy
// // must stay valid until we unsubscribe from notificatons. This
// // means we have to keep a reference to the object inside the
// // UpnpManager as long as we are subscribed to notifications.
// gupnp_service_proxy_set_subscribed(GUPNP_SERVICE_PROXY(serviceInfo), true);
// }
// }
// g_object_unref (childService->data);
// childService = g_list_delete_link (childService, childService);
// }
// }
GUPnPDeviceInfo *deviceInfo = GUPNP_DEVICE_INFO(proxy);
UpnpResource::Ptr pUpnpResource;
const string udn = gupnp_device_info_get_udn(deviceInfo);
bool isRoot = *(static_cast <bool *> (userData));
DEBUG_PRINT("Device type: " << gupnp_device_info_get_device_type(deviceInfo));
// For now, lights only
if (! boost::regex_match(gupnp_device_info_get_device_type(deviceInfo), boost::regex(".*[Ll]ight.*")))
{
ERROR_PRINT("Device type " << gupnp_device_info_get_device_type(deviceInfo) << " not implemented");
return;
}
#ifndef NDEBUG
char *devModel = gupnp_device_info_get_model_name(deviceInfo);
if (devModel != NULL)
{
DEBUG_PRINT("\tDevice model: " << devModel);
g_free(devModel);
}
char *devName = gupnp_device_info_get_friendly_name(deviceInfo);
if (devName != NULL)
{
DEBUG_PRINT("\tFriendly name: " << devName);
g_free(devName);
}
#endif
DEBUG_PRINT("\tUdn: " << udn);
if (isRoot)
{
// Root device
pUpnpResource = s_manager->processDevice(proxy, deviceInfo, true, &s_requestState);
}
else
{
pUpnpResource = s_manager->processDevice(proxy, deviceInfo, false, &s_requestState);
}
if (pUpnpResource != nullptr && !pUpnpResource->isRegistered())
{
DEBUG_PRINT("Register device resource: " << pUpnpResource->m_uri);
if (s_discoveryCallback(pUpnpResource) == 0)
{
pUpnpResource->setRegistered(true);
}
else
{
pUpnpResource->setRegistered(false);
unregisterDeviceResource(udn);
return;
}
// Traverse the service list and register all the services where isReady() returns true.
// This is done in order to catch all the services that have been seen
// prior to discovering the hosting device.
GList *childService = gupnp_device_info_list_services (deviceInfo);
while (childService)
{
GUPnPServiceInfo *serviceInfo = GUPNP_SERVICE_INFO (childService->data);
std::shared_ptr<UpnpResource> pUpnpResourceService = s_manager->findResource(serviceInfo);
if (pUpnpResourceService == nullptr)
{
DEBUG_PRINT("Registering device: Service link is empty!");
// This could happen if support for the service is not implemented
}
else
{
DEBUG_PRINT(pUpnpResourceService->m_uri << "ready " << pUpnpResourceService->isReady() <<
" and registered " << pUpnpResourceService->isRegistered());
if (pUpnpResourceService->isReady() && !pUpnpResourceService->isRegistered())
{
DEBUG_PRINT("Register resource for previously discovered child service: " <<
pUpnpResourceService->m_uri);
s_discoveryCallback(pUpnpResourceService);
pUpnpResourceService->setRegistered(true);
// Subscribe to notifications
// Important!!! UpnpService object associated with this info/proxy
// must stay valid until we unsubscribe from notificatons. This
// means we have to keep a reference to the object inside the
// UpnpManager as long as we are subscribed to notifications.
gupnp_service_proxy_set_subscribed(GUPNP_SERVICE_PROXY(serviceInfo), true);
}
}
g_object_unref (childService->data);
childService = g_list_delete_link (childService, childService);
}
}
}
void UpnpConnector::onServiceProxyAvailable(GUPnPControlPoint *controlPoint,
......@@ -626,6 +635,28 @@ OCEntityHandlerResult handleEntityHandlerRequests( OCEntityHandlerRequest *entit
}
}
for (const auto& device : s_manager->m_devices) {
if (device.second->m_uri == uri) {
switch (entityHandlerRequest->method)
{
case OC_REST_GET:
DEBUG_PRINT(" GET Request for: " << uri);
ehResult = device.second->processGetRequest(payload);
break;
case OC_REST_PUT:
case OC_REST_POST:
DEBUG_PRINT("PUT / POST Request on " << uri << " are not supported");
// fall thru intentionally
default:
DEBUG_PRINT("UnSupported Method [" << entityHandlerRequest->method << "] Received");
ConcurrentIotivityUtils::respondToRequestWithError(entityHandlerRequest, " Unsupported Method", OC_EH_METHOD_NOT_ALLOWED);
return OC_EH_ERROR;
}
}
}
responsePayload = getCommonPayload(uri.c_str(), interfaceQuery, resourceType, payload);
ConcurrentIotivityUtils::respondToRequest(entityHandlerRequest, responsePayload, ehResult);
OICFree(dupQuery);
......@@ -654,7 +685,11 @@ OCEntityHandlerResult resourceEntityHandler(OCEntityHandlerFlag,
uintptr_t callbackParamResourceType = (uintptr_t)callback;
std::string resourceType;
if (callbackParamResourceType == BINARY_SWITCH_CALLBACK)
if (callbackParamResourceType == LIGHT_CALLBACK)
{
return handleEntityHandlerRequests(entityHandlerRequest, UPNP_OIC_TYPE_DEVICE_LIGHT);
}
else if (callbackParamResourceType == BINARY_SWITCH_CALLBACK)
{
return handleEntityHandlerRequests(entityHandlerRequest, UPNP_OIC_TYPE_POWER_SWITCH);
}
......@@ -695,4 +730,19 @@ void UpnpConnector::onAdd(std::string uri)
}
}
}
for (const auto& device : s_manager->m_devices) {
if (device.second->m_uri == uri) {
if (device.second->m_resourceType == UPNP_OIC_TYPE_DEVICE_LIGHT) {
DEBUG_PRINT("Adding light device");
ConcurrentIotivityUtils::queueCreateResource(uri, UPNP_OIC_TYPE_DEVICE_LIGHT, OC_RSRVD_INTERFACE_ACTUATOR,
resourceEntityHandler,
(void *) LIGHT_CALLBACK, resourceProperties);
}
else
{
DEBUG_PRINT("No device added for " << device.second->m_resourceType);
}
}
}
}
......@@ -168,3 +168,78 @@ string UpnpDevice::getStringField(function< char *(GUPnPDeviceInfo *deviceInfo)>
}
return "";
}
OCEntityHandlerResult UpnpDevice::processGetRequest(OCRepPayload *payload)
{
if (payload == NULL)
{
throw "payload is null";
}
GUPnPDeviceInfo *deviceInfo = GUPNP_DEVICE_INFO(m_proxy);
if (!OCRepPayloadSetPropString(payload, "device_type", m_deviceType.c_str()))
{
throw "Failed to set device_type value in payload";
}
DEBUG_PRINT("device_type: " << m_deviceType);
for (auto const &kv : s_deviceInfo2AttributesMap)
{
char *c_field = kv.second(deviceInfo);
if (c_field != NULL)
{
string s_field = string(c_field);
if (!OCRepPayloadSetPropString(payload, kv.first.c_str(), s_field.c_str()))
{
throw "Failed to set property value in payload";
}
DEBUG_PRINT(kv.first << ": " << s_field);
g_free(c_field);
}
}
char *iconUrl = gupnp_device_info_get_icon_url(deviceInfo, NULL, -1, -1, -1, false, NULL, NULL, NULL, NULL);
if (iconUrl != NULL)
{
if (!OCRepPayloadSetPropString(payload, "icon_url", iconUrl))
{
throw "Failed to set icon_url value in payload";
}
DEBUG_PRINT("icon_url: " << iconUrl);
g_free(iconUrl);
}
if (!OCRepPayloadSetPropString(payload, "name", m_name.c_str()))
{
throw "Failed to set name in payload";
}
DEBUG_PRINT("name: " << m_name);
if (!OCRepPayloadSetPropString(payload, "uri", m_uri.c_str()))
{
throw "Failed to set uri in payload";
}
DEBUG_PRINT("uri: " << m_uri);
if (!m_links.empty())
{
DEBUG_PRINT("Setting links");
const OCRepPayload *links[m_links.size()];
size_t dimensions[MAX_REP_ARRAY_DEPTH] = {m_links.size(), 0, 0};
for (unsigned int i = 0; i < m_links.size(); ++i) {
DEBUG_PRINT("link[" << i << "]");
DEBUG_PRINT("\thref=" << m_links[i].href);
DEBUG_PRINT("\trel=" << m_links[i].rel);
DEBUG_PRINT("\trt=" << m_links[i].rt);
OCRepPayload *linkPayload = OCRepPayloadCreate();
OCRepPayloadSetPropString(linkPayload, "href", m_links[i].href.c_str());
OCRepPayloadSetPropString(linkPayload, "rel", m_links[i].rel.c_str());
OCRepPayloadSetPropString(linkPayload, "rt", m_links[i].rt.c_str());
links[i] = linkPayload;
}
OCRepPayloadSetPropObjectArray(payload, "links", links, dimensions);
}
return OC_EH_OK;
}
......@@ -51,6 +51,8 @@ class UpnpDevice: public UpnpResource
std::vector<string> &getDeviceList();
std::vector<string> &getServiceList();
OCEntityHandlerResult processGetRequest(OCRepPayload *payload);
private:
GUPnPDeviceProxy *m_proxy;
......
......@@ -316,6 +316,10 @@ void UpnpManager::onScan()
for (const auto& service : m_services) {
MPMSendResponse(service.second->m_uri.c_str(), service.second->m_uri.size(), MPM_SCAN);
}
for (const auto& device : m_devices) {
MPMSendResponse(device.second->m_uri.c_str(), device.second->m_uri.size(), MPM_SCAN);
}
}
UpnpResource::Ptr UpnpManager::findResource(GUPnPServiceInfo *info)
......@@ -330,7 +334,7 @@ UpnpResource::Ptr UpnpManager::findResource(GUPnPDeviceInfo *info)
std::shared_ptr<UpnpService> UpnpManager::findService(std::string serviceKey)
{
DEBUG_PRINT("");
DEBUG_PRINT("serviceKey = " << serviceKey);
std::map< string, shared_ptr<UpnpService> >::iterator it = m_services.find(serviceKey);
if (it != m_services.end())
......@@ -343,6 +347,7 @@ std::shared_ptr<UpnpService> UpnpManager::findService(std::string serviceKey)
shared_ptr<UpnpDevice> UpnpManager::findDevice(string udn)
{
DEBUG_PRINT("udn = " << udn);
std::map< string, shared_ptr<UpnpDevice> >::iterator it = m_devices.find(udn);
if (it != m_devices.end())
......
......@@ -40,13 +40,12 @@ class UpnpManager
std::shared_ptr<UpnpService> findService(std::string serviceKey);
// TODO make this private access it through accessors.
// Device map, keyed off device UDN
std::map<std::string, std::shared_ptr<UpnpDevice> > m_devices;
// Service map, keyed off service ID
std::map<std::string, std::shared_ptr<UpnpService> > m_services;
private:
// Device map, keyed off device UDN
std::map<std::string, std::shared_ptr<UpnpDevice> > m_devices;
std::shared_ptr<UpnpDevice> addDevice(GUPnPDeviceInfo *info,
const string parent,
......
......@@ -62,6 +62,14 @@ void UpnpResource::addLink(UpnpResource::Ptr pResource)
// singleLink["rt"] = pResource->getResourceType();
//
// m_links.push_back(singleLink);
_link singleLink;
singleLink.href = pResource->m_uri;
singleLink.rel = "contains";
singleLink.rt = pResource->getResourceType();
m_links.push_back(singleLink);
}
void UpnpResource::setLinkAttribute()
......
......@@ -29,6 +29,12 @@
using namespace std;
struct _link {
string href;
string rel;
string rt;
};
class UpnpResource
{
public:
......@@ -57,6 +63,7 @@ class UpnpResource
std::string m_interface;
std::string m_address;
// CompositeAttribute m_links;
vector<_link> m_links;
string m_udn;
bool m_ready;
bool m_registered;
......
......@@ -45,16 +45,17 @@ FILE *sec_file(const char *, const char *mode)
}
static UpnpConnector *s_upnpConnector;
std::vector< UpnpResource::Ptr > m_vecResources;
int connectorDiscoveryCb(UpnpResource::Ptr pUpnpResource)
{
int result = 1;
int result = 0;
DEBUG_PRINT("UpnpResource URI " << pUpnpResource->m_uri);
//result = m_pResourceContainer->registerResource(pUpnpResource);
if (result == 0)
{
//m_vecResources.push_back(pUpnpResource);
m_vecResources.push_back(pUpnpResource);
} else {
ERROR_PRINT(result << " Failed to register resource: " << pUpnpResource->m_uri);
}
......
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