Commit 7180e0c3 authored by Jacob Gladish's avatar Jacob Gladish

Merge pull request #4 from brendanlong/blong/bridge-device

Fill in enough of BridgeDevice to expose AllJoyn devices from the adapter over the network.
parents d660d1d6 23fbedf7
......@@ -22,7 +22,7 @@ adapters::mock::MockAdapter::MockAdapter()
, m_adapterName("DSB Mock Adapter")
, m_exposedAdapterPrefix("com." + m_vendor)
, m_exposedApplicationName("DeviceSystemBridge")
, m_exposedApplicationGuid("C27BC425-0058-4829-8775-441B5D8740C0")
, m_exposedApplicationGuid(common::Guid::Parse("C27BC425-0058-4829-8775-441B5D8740C0"))
{
// TODO: get m_exposedApplicatioName and Prefix from config
}
......@@ -62,7 +62,7 @@ adapters::mock::MockAdapter::GetExposedApplicationName()
return m_exposedApplicationName;
}
std::string
common::Guid
adapters::mock::MockAdapter::GetExposedApplicationGuid()
{
return m_exposedApplicationGuid;
......@@ -91,7 +91,6 @@ adapters::mock::MockAdapter::Shutdown()
m_version.clear();
m_exposedAdapterPrefix.clear();
m_exposedApplicationName.clear();
m_exposedApplicationGuid.clear();
m_devices.clear();
m_signals.clear();
......
......@@ -23,7 +23,7 @@ namespace mock
virtual std::string GetVersion();
virtual std::string GetExposedAdapterPrefix();
virtual std::string GetExposedApplicationName();
virtual std::string GetExposedApplicationGuid();
virtual common::Guid GetExposedApplicationGuid();
virtual bridge::AdapterSignalVector GetSignals();
virtual int32_t Initialize();
......@@ -77,7 +77,7 @@ namespace mock
std::string m_version;
std::string m_exposedAdapterPrefix;
std::string m_exposedApplicationName;
std::string m_exposedApplicationGuid;
common::Guid m_exposedApplicationGuid;
std::vector< shared_ptr<MockAdapterDevice> > m_devices;
std::vector< shared_ptr<MockAdapterSignal> > m_signals;
......
......@@ -182,6 +182,11 @@ std::string MockAdapterDevice::GetDescription()
return m_description;
}
shared_ptr<bridge::IAdapterIcon> MockAdapterDevice::GetIcon()
{
return m_icon;
}
bridge::AdapterPropertyVector const& MockAdapterDevice::GetProperties() const
{
return m_properties;
......
......@@ -116,6 +116,7 @@ namespace mock
virtual std::string GetFirmwareVersion();
virtual std::string GetSerialNumber();
virtual std::string GetDescription();
virtual shared_ptr<bridge::IAdapterIcon> GetIcon();
virtual bridge::AdapterPropertyVector const& GetProperties() const;
virtual bridge::AdapterMethodVector const& GetMethods() const;
......@@ -150,6 +151,7 @@ namespace mock
std::string m_firmwareVersion;
std::string m_serialNumber;
std::string m_description;
shared_ptr<bridge::IAdapterIcon> m_icon;
bridge::AdapterPropertyVector m_properties;
bridge::AdapterMethodVector m_methods;
bridge::AdapterSignalVector m_signalPrototypes;
......
......@@ -7,7 +7,7 @@ namespace
std::string const kVersion("1.0");
std::string const kExposedPrefix("com.allseen");
std::string const kExposedAppName("The ZigBee Adapter");
std::string const kExposedGuid("B8D50823-9F64-4110-AA0C-3CB3D17B73F2");
common::Guid const kExposedGuid = common::Guid::Parse("B8D50823-9F64-4110-AA0C-3CB3D17B73F2");
}
adapter::zigbee::Adapter::Adapter()
......@@ -48,7 +48,7 @@ adapter::zigbee::Adapter::GetExposedApplicationName()
return kExposedAppName;
}
std::string
common::Guid
adapter::zigbee::Adapter::GetExposedApplicationGuid()
{
return kExposedGuid;
......
......@@ -55,7 +55,7 @@ namespace zigbee
virtual std::string GetVersion();
virtual std::string GetExposedAdapterPrefix();
virtual std::string GetExposedApplicationName();
virtual std::string GetExposedApplicationGuid();
virtual common::Guid GetExposedApplicationGuid();
virtual bridge::AdapterSignalVector GetSignals();
virtual int32_t Initialize();
......
......@@ -181,15 +181,15 @@ AllJoynAbout::SetDescription(char const* s)
}
QStatus
AllJoynAbout::AddObject(ajn::BusObject& obj, ajn::InterfaceDescription const* ifc)
AllJoynAbout::AddObject(ajn::BusObject& obj, ajn::InterfaceDescription const& ifc)
{
return obj.SetAnnounceFlag(ifc, ajn::BusObject::ANNOUNCED);
return obj.SetAnnounceFlag(&ifc, ajn::BusObject::ANNOUNCED);
}
QStatus
AllJoynAbout::RemoveObject(ajn::BusObject& obj, ajn::InterfaceDescription const* ifc)
AllJoynAbout::RemoveObject(ajn::BusObject& obj, ajn::InterfaceDescription const& ifc)
{
return obj.SetAnnounceFlag(ifc, ajn::BusObject::UNANNOUNCED);
return obj.SetAnnounceFlag(&ifc, ajn::BusObject::UNANNOUNCED);
}
QStatus
......
......@@ -20,8 +20,8 @@ namespace bridge
QStatus Initialize(ajn::BusAttachment& bus);
QStatus Shutdown();
QStatus Announce();
QStatus AddObject(ajn::BusObject& obj, ajn::InterfaceDescription const* ifc);
QStatus RemoveObject(ajn::BusObject& obj, ajn::InterfaceDescription const* ifc);
QStatus AddObject(ajn::BusObject& obj, ajn::InterfaceDescription const& ifc);
QStatus RemoveObject(ajn::BusObject& obj, ajn::InterfaceDescription const& ifc);
// TODO: are these really needed?
QStatus SetManufacturer(char const* s);
......
#include "BridgeDevice.h"
#include "AllJoynHelper.h"
#include "DsbServiceNames.h"
#include "Common/Log.h"
bridge::BridgeDevice::BridgeDevice(const shared_ptr<IAdapterDevice>& dev, const shared_ptr<IAdapter>& adapter)
: m_parent(dev)
namespace
{
DSB_DECLARE_LOGNAME(BridgeDevice);
}
bridge::BridgeDevice::BridgeDevice(const shared_ptr<IAdapterDevice>& device, const shared_ptr<IAdapter>& adapter)
: m_device(device)
, m_adapter(adapter)
, m_busAttachment(AllJoynHelper::EncodeStringForAppName(adapter->GetExposedApplicationName()).c_str(), true)
, m_deviceMain(*this, device)
{
}
......@@ -16,14 +25,231 @@ bridge::BridgeDevice::~BridgeDevice()
QStatus
bridge::BridgeDevice::Shutdown()
{
QStatus st = ER_OK;
return st;
RegisterSignalHandlers(false);
m_about.Shutdown();
// TODO: Shutdown icon, control panel, device properties, interface
ShutdownAllJoyn();
m_serviceName.clear();
return ER_OK;
}
QStatus
bridge::BridgeDevice::Initialize()
{
QStatus st = ER_OK;
QStatus st;
ajn::InterfaceDescription* interface;
// create Device service name
st = BuildServiceName();
if (st != ER_OK)
goto leave;
// init alljoyn
st = InitializeAllJoyn();
if (st != ER_OK)
goto leave;
// initialize about service
st = m_about.Initialize(m_busAttachment);
if (st != ER_OK)
goto leave;
// set device info in about
m_about.SetApplicationName(m_adapter->GetExposedApplicationName().c_str());
m_about.SetApplicationGuid(m_adapter->GetExposedApplicationGuid());
m_about.SetDeviceName(m_device->GetName().c_str());
m_about.SetManufacturer(m_device->GetVendor().c_str());
m_about.SetModel(m_device->GetModel().c_str());
m_about.SetVersion(m_device->GetVersion().c_str());
m_about.SetDeviceId(m_device->GetSerialNumber().c_str());
m_about.SetDescription(m_device->GetDescription().c_str());
// TODO: If an Icon is available, try to add it to the bus attachment too. Just continue on error
//if (m_device->GetIcon() != NULL)
// m_icon.Initialize(m_busAttachment, m_device->GetIcon());
// create device properties
st = CreateDeviceProperties();
if (st != ER_OK)
goto leave;
// create main device
st = m_deviceMain.Initialize();
if (st != ER_OK)
goto leave;
// Create a control panel if requested by the caller.
st = InitControlPanel();
if (st != ER_OK)
goto leave;
// Create Lighting Service if requested
st = InitLightingService();
if (st != ER_OK)
goto leave;
interface = m_deviceMain.GetInterfaceDescription();
if (!interface)
{
DSBLOG_WARN("No interface description for DeviceMain");
return ER_FAIL;
}
m_about.AddObject(m_deviceMain, *interface);
// connect to AllJoyn
st = ConnectToAllJoyn();
if (st != ER_OK)
goto leave;
// register signals
st = RegisterSignalHandlers(true);
if (st != ER_OK)
goto leave;
// announce
m_about.Announce();
leave:
if (st != ER_OK)
Shutdown();
return st;
}
QStatus
bridge::BridgeDevice::BuildServiceName()
{
m_rootStringForAllJoynNames.clear();
m_serviceName.clear();
// set root/prefix for AllJoyn service name (aka bus name) and interface names :
// 'prefixForAllJoyn'.'AdapterName'.'DeviceName'
std::string tmp = AllJoynHelper::EncodeStringForRootServiceName(m_adapter->GetExposedAdapterPrefix());
if (tmp.empty())
return ER_BUS_BAD_BUS_NAME;
m_rootStringForAllJoynNames = tmp;
tmp = AllJoynHelper::EncodeStringForServiceName(m_adapter->GetAdapterName());
if (tmp.empty())
return ER_BUS_BAD_BUS_NAME;
m_rootStringForAllJoynNames += ".";
m_rootStringForAllJoynNames += tmp;
// set service name (aka bus name)
m_serviceName = m_rootStringForAllJoynNames;
//add device name
tmp = AllJoynHelper::EncodeStringForServiceName(m_device->GetName());
if (!tmp.empty())
{
m_serviceName += ".";
m_serviceName += tmp;
}
// add serial number to service name if not empty
tmp = AllJoynHelper::EncodeStringForServiceName(m_device->GetSerialNumber());
if (!tmp.empty())
{
m_serviceName += ".";
m_serviceName += tmp;
}
return ER_OK;
}
QStatus
bridge::BridgeDevice::CreateDeviceProperties()
{
DSBLOG_NOT_IMPLEMENTED();
return ER_OK;
}
QStatus
bridge::BridgeDevice::RegisterSignalHandlers(bool)
{
DSBLOG_NOT_IMPLEMENTED();
return ER_OK;
}
QStatus
bridge::BridgeDevice::InitializeAllJoyn()
{
m_busAttachment.RegisterBusListener(*this);
QStatus st = m_busAttachment.Start();
if (st != ER_OK)
return st;
// TODO: Initialize authentication handler
return st;
}
QStatus
bridge::BridgeDevice::ConnectToAllJoyn()
{
QStatus st = m_busAttachment.Connect();
if (st != ER_OK)
return st;
/*
* Advertise this service on the bus.
* There are three steps to advertising this service on the bus.
* 1) Request a well-known name that will be used by the client to discover
* this service.
* 2) Create a session.
* 3) Advertise the well-known name.
*/
st = m_busAttachment.RequestName(m_serviceName.c_str(), DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE);
if (st != ER_OK)
return st;
ajn::SessionOpts sessionOpts(ajn::SessionOpts::TRAFFIC_MESSAGES, true, ajn::SessionOpts::PROXIMITY_ANY, ajn::TRANSPORT_ANY);
ajn::SessionPort sessionPort = DSB_SERVICE_PORT;
st = m_busAttachment.BindSessionPort(sessionPort, sessionOpts, *this);
if (st != ER_OK)
return st;
st = m_busAttachment.AdvertiseName(m_serviceName.c_str(), sessionOpts.transports);
if (st != ER_OK)
return st;
return ER_OK;
}
QStatus
bridge::BridgeDevice::ShutdownAllJoyn()
{
if (!m_serviceName.empty())
m_busAttachment.CancelAdvertiseName(m_serviceName.c_str(), ajn::TRANSPORT_ANY);
m_busAttachment.UnbindSessionPort(DSB_SERVICE_PORT);
if (!m_serviceName.empty())
m_busAttachment.ReleaseName(m_serviceName.c_str());
m_busAttachment.Disconnect();
//TODO: m_authHandler.Shutdown();
m_busAttachment.Stop();
return ER_OK;
}
QStatus
bridge::BridgeDevice::InitControlPanel()
{
DSBLOG_NOT_IMPLEMENTED();
return ER_OK;
}
QStatus
bridge::BridgeDevice::InitLightingService()
{
DSBLOG_NOT_IMPLEMENTED();
return ER_OK;
}
#pragma once
#include "Bridge/IAdapter.h"
#include "AllJoynAbout.h"
#include "IAdapter.h"
#include "DeviceMain.h"
#include "DeviceProperty.h"
#include <alljoyn/BusAttachment.h>
namespace bridge
{
class BridgeDevice
class BridgeDevice : private ajn::SessionPortListener, private ajn::BusListener
{
public:
BridgeDevice(const shared_ptr<IAdapterDevice>&, const shared_ptr<IAdapter>&);
......@@ -21,12 +24,32 @@ namespace bridge
shared_ptr<IAdapterDevice> GetAdapterDevice()
{
return m_parent;
return m_device;
}
inline std::string &GetRootNameForInterface()
{
return m_rootStringForAllJoynNames;
}
private:
shared_ptr<IAdapterDevice> m_parent;
QStatus BuildServiceName();
QStatus InitializeAllJoyn();
QStatus CreateDeviceProperties();
QStatus InitControlPanel();
QStatus InitLightingService();
QStatus ConnectToAllJoyn();
QStatus ShutdownAllJoyn();
QStatus RegisterSignalHandlers(bool isRegister);
shared_ptr<IAdapterDevice> m_device;
shared_ptr<IAdapter> m_adapter;
ajn::BusAttachment m_busAttachment;
DeviceMain m_deviceMain;
AllJoynAbout m_about;
std::string m_rootStringForAllJoynNames;
std::string m_serviceName;
std::map<std::string, shared_ptr<DeviceProperty>> m_deviceProperties;
};
}
#include "DeviceMain.h"
#include "AllJoynHelper.h"
#include "BridgeDevice.h"
#include "Common/Log.h"
namespace
{
DSB_DECLARE_LOGNAME(DeviceMain);
static const std::string INTERFACE_NAME_FOR_MAIN_DEVICE(".MainInterface");
}
static std::string BuildBusObjectPath(const std::string& name)
......@@ -15,11 +17,12 @@ static std::string BuildBusObjectPath(const std::string& name)
return "/" + encodedName;
}
bridge::DeviceMain::DeviceMain(BridgeDevice& parent)
: ajn::BusObject(BuildBusObjectPath(m_parent.GetAdapterDevice()->GetName()).c_str(), false)
bridge::DeviceMain::DeviceMain(BridgeDevice& parent, const shared_ptr<IAdapterDevice>& adapterDevice)
: ajn::BusObject(BuildBusObjectPath(adapterDevice->GetName()).c_str(), false)
, m_parent(parent)
, m_indexForSignal(1)
, m_indexForMethod(1)
, m_interfaceDescription(NULL)
, m_registeredOnAllJoyn(false)
{
}
......@@ -43,6 +46,12 @@ bridge::DeviceMain::Initialize()
if (st != ER_OK)
return st;
if (!m_interfaceDescription)
{
DSBLOG_ERROR("Interface description does not exist for bus object");
return ER_FAIL;
}
st = AddInterface(*m_interfaceDescription);
if (st != ER_OK)
{
......@@ -72,6 +81,8 @@ bridge::DeviceMain::Initialize()
{
DSBLOG_WARN("Failed to register bus object: %s", QCC_StatusText(st));
return st;
} else {
DSBLOG_INFO("Registered bus object for %s", m_interfaceName.c_str());
}
m_registeredOnAllJoyn = true;
......@@ -88,18 +99,46 @@ bool
bridge::DeviceMain::IsSignalNameUnique(std::string const&)
{
// TODO:
DSBLOG_NOT_IMPLEMENTED();
return false;
}
QStatus
bridge::DeviceMain::CreateMethodsAndSignals()
{
// TODO
m_interfaceName = m_parent.GetRootNameForInterface();
std::string tmp = AllJoynHelper::EncodeStringForServiceName(m_parent.GetAdapterDevice()->GetName());
if (!tmp.empty())
{
m_interfaceName += ".";
m_interfaceName += tmp;
}
m_interfaceName += INTERFACE_NAME_FOR_MAIN_DEVICE;
// TODO: Handle security
QStatus st = m_parent.GetBusAttachment().CreateInterface(m_interfaceName.c_str(), m_interfaceDescription, ajn::InterfaceSecurityPolicy::AJ_IFC_SECURITY_INHERIT);
if (st != ER_OK || m_interfaceDescription == NULL)
{
DSBLOG_WARN("Failed to create interface for %s: %s", m_interfaceName.c_str(), QCC_StatusText(st));
return st;
}
// TODO: Create methods and signals
m_interfaceDescription->Activate();
return st;
}
ajn::InterfaceDescription*
bridge::DeviceMain::GetInterfaceDescription()
{
DSBLOG_NOT_IMPLEMENTED();
return ER_NOT_IMPLEMENTED;
return m_interfaceDescription;
}
void
bridge::DeviceMain::AJMethod(const ajn::InterfaceDescription::Member*, ajn::Message&)
{
DSBLOG_NOT_IMPLEMENTED();
}
#ifndef __DEVICE_MAIN_H__
#define __DEVICE_MAIN_H__
#include "BridgeDevice.h"
#include <map>
#include <alljoyn/BusObject.h>
#include <alljoyn/InterfaceDescription.h>
#include "IAdapter.h"
namespace bridge
{
class BridgeDevice;
class DeviceMethod;
class DeviceSignal;
class DeviceMain : private ajn::BusObject
class DeviceMain : public ajn::BusObject
{
DeviceMain(BridgeDevice& parent);
public:
DeviceMain(BridgeDevice& parent, const shared_ptr<IAdapterDevice>&);
virtual ~DeviceMain();
QStatus Initialize();
......@@ -23,6 +26,8 @@ namespace bridge
bool IsSignalNameUnique(std::string const& name);
void HandleSignal(IAdapterSignal const& adapterSignal);
ajn::InterfaceDescription* GetInterfaceDescription();
inline int GetIndexForMethod()
{ return m_indexForMethod++; }
......@@ -38,7 +43,7 @@ namespace bridge
BridgeDevice& m_parent;
int m_indexForSignal;
int m_indexForMethod;
std::unique_ptr<ajn::InterfaceDescription> m_interfaceDescription;
ajn::InterfaceDescription* m_interfaceDescription;
std::string m_interfaceName;
std::map<std::string, DeviceMethod* > m_deviceMethods;
std::map<std::string, DeviceSignal* > m_deviceSignals;
......
#pragma once
//static const char* DSB_DEVICENOTIFICATION_SIGNAL = "DeviceNotificationSignal";
//static const char* DSB_SENDMSGTODEVICE_METHOD = "SendMessageToDeviceSynchronous";
static const ajn::SessionPort DSB_SERVICE_PORT = 1000;
#pragma once
#include "Common/defines.h"
#include "Common/Guid.h"
#include "Common/Variant.h"
#include <string>
......@@ -80,6 +81,14 @@ namespace bridge
virtual void AdapterSignalHandler(IAdapterSignal const& signal, void* argp) = 0;
};
class IAdapterIcon
{
public:
virtual std::vector<uint8_t> GetImage() = 0;
virtual std::string GetMimeType() = 0;
virtual std::string GetUrl() = 0;
};
class IAdapterDevice
{
public:
......@@ -91,6 +100,7 @@ namespace bridge
virtual std::string GetFirmwareVersion() = 0;
virtual std::string GetSerialNumber() = 0;
virtual std::string GetDescription() = 0;
virtual shared_ptr<IAdapterIcon> GetIcon() = 0;
virtual AdapterPropertyVector const& GetProperties() const = 0;
virtual AdapterMethodVector const& GetMethods() const = 0;
......@@ -125,7 +135,7 @@ namespace bridge
virtual std::string GetVersion() = 0;
virtual std::string GetExposedAdapterPrefix() = 0;
virtual std::string GetExposedApplicationName() = 0;
virtual std::string GetExposedApplicationGuid() = 0;
virtual common::Guid GetExposedApplicationGuid() = 0;
virtual AdapterSignalVector GetSignals() = 0;
virtual int32_t Initialize() = 0;
......
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