~~~~~~~~~~~~~{.json}
{
- "mainloop" : "/usr/lib/i386-linux-gnu/automotive-message-broker/qtmainloopplugin.so",
+ "mainloop" : "/usr/lib/x86_64-linux-gnu/automotive-message-broker/qtmainloopplugin.so",
"plugins" : "/etc/ambd/plugins.d"
}
~~~~~~~~~~~~~
return ::std::unique_ptr<T>(t);
}
+template<typename T> ::std::shared_ptr<T> make_shared(T* t)
+{
+ return ::std::shared_ptr<T>(t);
+}
+
template<typename T> gobject_ptr<T> make_gobject(T* t)
{
return gobject_ptr<T>(t, [](auto ptr) { if(ptr) g_object_unref(ptr);});
double currentTime();
+/*!
+ * \brief The Timestamp class provides system time and monotonic time helper functions
+ * Timestamp is meant to be a singleton class. Access through instance().
+ * \code
+ * double currentMonotonicTime = amb::Timestamp::instance()->currentTime();
+ * double epocTimeForMonotonicTime = amb::Timestamp::instance()->epochTime(currentMonotonicTime);
+ * \endcode
+ */
class Timestamp {
protected:
Timestamp();
public:
+ /*!
+ * \brief currentTime
+ * \return current monotonic (steady) time in seconds.
+ */
double currentTime();
+ /*!
+ * \brief epochTime
+ * \param time monotonic time usually from currentTime()
+ * \return number of seconds.milliseconds since unix epoch
+ */
double epochTime(double time);
+ /*!
+ * \brief epochTime
+ * \return current system time in seconds since unix epoch
+ */
double epochTime();
public:
+ /*!
+ * \brief instance
+ * \return instance of Timestamp;
+ */
static Timestamp *instance();
private:
}
amb::AmbRemoteClient::AmbRemoteClient(AbstractIo *io)
- :BaseJsonMessageReader(io)
+ :BaseJsonMessageReader(io), serverTimeOffset(0)
{
}
GetMethodCall getCall;
getCall.sourceUuid = sourceUuid;
getCall.zone = zone;
- getCall.value = Object(objectName);
+ getCall.value = amb::make_shared(new Object(objectName));
mGetMethodCalls[getCall.messageId] = cb;
send(getCall);
}
-void amb::AmbRemoteClient::set(const string &objectName, const Object & value, SetCallback cb)
+void amb::AmbRemoteClient::set(const string &objectName, Object::ObjectPtr value, SetCallback cb)
{
set(objectName, value, "", Zone::None, cb);
}
-void amb::AmbRemoteClient::set(const string &objectName, const Object & value, const string &sourceUuid, Zone::Type zone, SetCallback cb)
+void amb::AmbRemoteClient::set(const string &objectName, Object::ObjectPtr value, const string &sourceUuid, Zone::Type zone, SetCallback cb)
{
SetMethodCall setCall;
setCall.sourceUuid = sourceUuid;
send(setCall);
}
-void amb::AmbRemoteClient::listen(const string &objectName, const string &sourceUuid, Zone::Type zone, amb::AmbRemoteClient::ObjectCallback cb)
+const string amb::AmbRemoteClient::subscribe(const string &objectName, const string &sourceUuid, Zone::Type zone, amb::AmbRemoteClient::ObjectCallback cb)
{
+ std::string subscription = createSubscriptionId(objectName, sourceUuid, zone);
+ SubscribeMethodCall call(objectName);
+
+ Subscription sub(call, cb);
+
+ mSubscriptions[subscription].push_back(sub);
+
+ return call.messageId;
+}
+
+void amb::AmbRemoteClient::subscribe(const string &objectName, amb::AmbRemoteClient::ObjectCallback cb)
+{
+ subscribe(objectName, "", Zone::None, cb);
}
-void amb::AmbRemoteClient::listen(const string &objectName, amb::AmbRemoteClient::ObjectCallback cb)
+void amb::AmbRemoteClient::unsubscribe(const string &subscribeId)
{
+ for(auto i : mSubscriptions)
+ {
+ auto subscriptions = &i.second;
+ for(auto n : *subscriptions)
+ {
+ if(n.subscriptionId() == subscribeId)
+ {
+ removeOne(subscriptions, n);
+ if(!subscriptions->size())
+ {
+ UnsubscribeMethodCall call(n.call);
+
+ send(call);
+ }
+ }
+ }
+ }
}
void amb::AmbRemoteClient::hasJsonMessage(const picojson::value &json)
{
DebugOut(7) << "json: " << json.serialize() << endl;
- if(BaseMessage::is<MethodCall>(json))
+ if(BaseMessage::is<MethodReply<MethodCall>>(json))
{
- if(BaseMessage::is<ListMethodCall>(json))
+ if(BaseMessage::is<MethodReply<ListMethodCall>>(json))
{
- ListMethodCall listMethodCall;
- listMethodCall.fromJson(json);
+ MethodReply<ListMethodCall> listMethodReply;
+ listMethodReply.fromJson(json);
+
+ const ListMethodCallPtr listMethod = listMethodReply.method();
- if(mListCalls.find(listMethodCall.messageId) != mListCalls.end())
+ if(amb::containsKey(mListCalls, listMethod->messageId))
{
- auto cb = mListCalls[listMethodCall.messageId];
+ auto cb = mListCalls[listMethod->messageId];
try
{
- cb(listMethodCall.objectNames);
+ cb(listMethod->objectNames);
}
catch(...)
{
DebugOut(DebugOut::Warning) << "callback for 'list' is not valid" << endl;
}
- mListCalls.erase(listMethodCall.messageId);
+ mListCalls.erase(listMethod->messageId);
}
}
- else if(BaseMessage::is<GetMethodCall>(json))
+ else if(BaseMessage::is<MethodReply<GetMethodCall>>(json))
{
- GetMethodCall getCall;
- getCall.fromJson(json);
+ MethodReply<GetMethodCall> reply;
+ reply.fromJson(json);
+ GetMethodCallPtr getCall = reply.method();
- if(amb::containsKey(mGetMethodCalls, getCall.messageId))
+ if(amb::containsKey(mGetMethodCalls, getCall->messageId))
{
- auto cb = mGetMethodCalls[getCall.messageId];
+ auto cb = mGetMethodCalls[getCall->messageId];
try
{
- cb(getCall.value);
+ cb(getCall->value);
}
catch(...)
{
DebugOut(DebugOut::Warning) << "Invalid Get callback " << endl;
}
- mGetMethodCalls.erase(getCall.messageId);
+ mGetMethodCalls.erase(getCall->messageId);
}
}
- else if(BaseMessage::is<SetMethodCall>(json))
+ else if(BaseMessage::is<MethodReply<SetMethodCall>>(json))
+ {
+ MethodReply<SetMethodCall> reply;
+ reply.fromJson(json);
+
+ auto call = reply.method();
+
+ if(amb::containsKey(mSetMethodCalls, call->messageId))
+ {
+ auto cb = mSetMethodCalls[call->messageId];
+
+ try
+ {
+ cb(reply.methodSuccess);
+ }
+ catch(...)
+ {
+ DebugOut(DebugOut::Warning) << "Invalid Set callback " << endl;
+ }
+ mSetMethodCalls.erase(call->messageId);
+ }
+ }
+ else if(BaseMessage::is<MethodReply<TimeSyncMessage>>(json))
{
}
}
picojson::object obj = i.get<picojson::object>();
- Object ambObj = Object::fromJson(obj);
+ Object::ObjectPtr ambObj = Object::fromJson(obj);
objectNames.push_back(ambObj);
}
obj["source"] = picojson::value(sourceUuid);
obj["zone"] = picojson::value((double)zone);
- obj["methodSuccess"] = picojson::value(success);
return picojson::value(obj);
}
sourceUuid = json.get("source").to_str();
zone = json.get("zone").get<double>();
- if(json.contains("success"))
- success = json.get("methodSuccess").get<bool>();
-
return true;
}
}
-void amb::AmbRemoteServer::list(ListMethodCall &call)
+void amb::AmbRemoteServer::list(ListMethodCallPtr call)
{
}
-void amb::AmbRemoteServer::get(GetMethodCall & get)
+void amb::AmbRemoteServer::get(GetMethodCallPtr get)
{
}
-void amb::AmbRemoteServer::set()
+void amb::AmbRemoteServer::set(SetMethodCallPtr set)
{
}
-void amb::AmbRemoteServer::listen()
+void amb::AmbRemoteServer::subscribe(SubscribeMethodCallPtr call)
+{
+
+}
+
+void amb::AmbRemoteServer::unsubscribe(amb::UnsubscribeMethodCallPtr call)
{
}
{
if(BaseMessage::is<ListMethodCall>(json))
{
- ListMethodCall listCall;
-
- listCall.fromJson(json);
+ ListMethodCallPtr listCall = BaseMessage::create<ListMethodCall>();
+ listCall->fromJson(json);
list(listCall);
}
else if(BaseMessage::is<GetMethodCall>(json))
{
- GetMethodCall getCall;
- getCall.fromJson(json);
+ GetMethodCallPtr getCall = BaseMessage::create<GetMethodCall>();
+ getCall->fromJson(json);
get(getCall);
}
+ else if(BaseMessage::is<SetMethodCall>(json))
+ {
+ SetMethodCallPtr setCall = BaseMessage::create<SetMethodCall>();
+ setCall->fromJson(json);
+
+ set(setCall);
+ }
+ else if(BaseMessage::is<SubscribeMethodCall>(json))
+ {
+ SubscribeMethodCallPtr call = BaseMessage::create<SubscribeMethodCall>();
+ call->fromJson(json);
+
+ subscribe(call);
+ }
+ else if(BaseMessage::is<UnsubscribeMethodCall>(json))
+ {
+ UnsubscribeMethodCallPtr call = BaseMessage::create<UnsubscribeMethodCall>();
+ call->fromJson(json);
+
+ unsubscribe(call);
+ }
+ else if(BaseMessage::is<TimeSyncMessage>(json))
+ {
+ TimeSyncMessagePtr call(new TimeSyncMessage);
+ call->fromJson(json);
+
+ call->serverTime = amb::Timestamp::instance()->epochTime();
+
+ MethodReply<TimeSyncMessage> reply(call, true);
+
+ send(reply);
+ }
+ else
+ {
+ BaseMessage call;
+ call.fromJson(json);
+ DebugOut(DebugOut::Warning) << "Unhandled method call: " << call.name << endl;
+ }
+ }
+ else
+ {
+ BaseMessage message;
+ message.fromJson(json);
+
+ DebugOut(DebugOut::Warning) << "Unhandled message: type: " << message.type << " name: " << message.name << endl;
}
}
}
-amb::Object amb::Object::fromJson(const picojson::object &obj)
+amb::Object::ObjectPtr amb::Object::fromJson(const picojson::object &obj)
{
if(!amb::containsKey(obj, "interfaceName"))
{
DebugOut(DebugOut::Warning) << "object missing interfaceName" << endl;
- return Object();
+ return ObjectPtr(new Object());
}
- Object ambObj(obj.at("interfaceName").to_str());
+ Object * ambObj = new Object(obj.at("interfaceName").to_str());
for(auto i : obj)
{
if(i.second.is<picojson::object>())
{
- ambObj[i.first] = std::shared_ptr<AbstractPropertyType>(amb::jsonToProperty(i.second));
+ (*ambObj)[i.first] = std::shared_ptr<AbstractPropertyType>(amb::jsonToProperty(i.second));
}
}
- return ambObj;
+ return ObjectPtr(ambObj);
}
-picojson::value amb::Object::toJson(const amb::Object &obj)
+picojson::value amb::Object::toJson(const ObjectPtr &obj)
{
picojson::object jsonObj;
- jsonObj["interfaceName"] = picojson::value(obj.interfaceName);
- for(auto i : obj)
+ jsonObj["interfaceName"] = picojson::value(obj->interfaceName);
+ for(auto i : *obj.get())
{
jsonObj[i.first] = i.second->toJson();
}
MethodCall::fromJson(json);
value = Object::fromJson(json.get<picojson::object>());
+
+ return true;
+}
+
+
+picojson::value amb::SubscribeMethodCall::toJson()
+{
+ auto json = MethodCall::toJson();
+
+ auto obj = json.get<picojson::object>();
+
+ obj["interfaceName"] = picojson::value(interfaceName);
+
+ return picojson::value(obj);
+}
+
+bool amb::SubscribeMethodCall::fromJson(const picojson::value &json)
+{
+ if(!MethodCall::fromJson(json))
+ return false;
+
+ interfaceName = json.get("interfaceName").to_str();
+
+ return true;
+}
+
+
+picojson::value amb::TimeSyncMessage::toJson()
+{
+ auto val = BaseMessage::toJson();
+
+ auto obj = val.get<picojson::object>();
+
+ obj["serverTime"] = picojson::value(serverTime);
+
+ return picojson::value(obj);
+}
+
+bool amb::TimeSyncMessage::fromJson(const picojson::value &json)
+{
+ if(!BaseMessage::fromJson(json))
+ return false;
+
+ serverTime = json.get("serverTime").get<double>();
+
+ return true;
}
class Object : public std::unordered_map<std::string, std::shared_ptr<AbstractPropertyType>>
{
public:
+ typedef std::shared_ptr<Object> ObjectPtr;
+
Object(): std::unordered_map<std::string, std::shared_ptr<AbstractPropertyType>>() { }
Object(const std::string & ifaceName): std::unordered_map<std::string, std::shared_ptr<AbstractPropertyType>>(),
interfaceName(ifaceName)
}
- static Object fromJson(const picojson::object & obj);
+ static ObjectPtr fromJson(const picojson::object & obj);
- static picojson::value toJson(const Object & obj);
+ static picojson::value toJson(const ObjectPtr & obj);
std::string interfaceName;
-
};
class BaseMessage
return T::is(json);
}
+ template <class T>
+ static std::shared_ptr<T> create()
+ {
+ return std::shared_ptr<T>(new T());
+ }
+
protected:
picojson::value data;
{
public:
MethodCall(std::string name)
- :BaseMessage(name, "method"), zone(Zone::None), success(false)
+ :BaseMessage(name, "method"), zone(Zone::None)
{
}
MethodCall(const BaseMessage & other)
- :BaseMessage(other), zone(Zone::None), success(false)
+ :BaseMessage(other), zone(Zone::None)
{
name = other.name;
}
{
sourceUuid = other.sourceUuid;
zone = other.zone;
- success = other.success;
}
static bool is(const BaseMessage * msg)
std::string sourceUuid;
Zone::Type zone;
- bool success;
+};
+
+template <class T>
+class MethodReply
+{
+public:
+
+ MethodReply(): MethodReply(nullptr, false) {}
+ MethodReply(std::shared_ptr<T> t, bool success): mMethod(t), methodSuccess(success) { }
+ bool methodSuccess;
+
+ picojson::value toJson()
+ {
+ picojson::value v = mMethod->toJson();
+
+ picojson::object obj = v.get<picojson::object>();
+ obj["methodSuccess"] = picojson::value(methodSuccess);
+
+ return picojson::value(obj);
+ }
+
+ bool fromJson(const picojson::value & json)
+ {
+ if(!mMethod) mMethod = std::shared_ptr<T>(new T());
+ mMethod->fromJson(json);
+ methodSuccess = json.get("methodSuccess").get<bool>();
+
+ return true;
+ }
+
+ static bool is(const picojson::value & v)
+ {
+ return v.contains("methodSuccess") && T::is(v);
+ }
+
+ const std::shared_ptr<T> method() { return mMethod; }
+
+protected:
+ std::shared_ptr<T> mMethod;
};
class ListMethodCall : public MethodCall
picojson::value toJson();
bool fromJson(const picojson::value &json);
- std::vector<Object> objectNames;
+ std::vector<Object::ObjectPtr> objectNames;
static bool is(const BaseMessage * msg)
{
return json.get("name").to_str() == "get";
}
- Object value;
+ Object::ObjectPtr value;
};
class SetMethodCall : public MethodCall
static bool is(const picojson::value & json)
{
- return json.get("name").to_str() != "set";
+ return json.get("name").to_str() == "set";
+ }
+
+ Object::ObjectPtr value;
+};
+
+class SubscribeMethodCall : virtual public MethodCall
+{
+public:
+ SubscribeMethodCall()
+ :SubscribeMethodCall("")
+ {
+
+ }
+ SubscribeMethodCall(const std::string & ifaceName)
+ :MethodCall("subscribe"), interfaceName(ifaceName)
+ {
+
+ }
+
+ picojson::value toJson();
+ bool fromJson(const picojson::value &json);
+
+ static bool is(const BaseMessage *msg)
+ {
+ return msg->name == "subscribe";
+ }
+
+ static bool is(const picojson::value & json)
+ {
+ return json.get("name").to_str() == "subscribe";
+ }
+
+ std::string interfaceName;
+};
+
+class UnsubscribeMethodCall : virtual public MethodCall, public SubscribeMethodCall
+{
+public:
+ UnsubscribeMethodCall()
+ :UnsubscribeMethodCall("")
+ {
+
+ }
+
+ UnsubscribeMethodCall(const SubscribeMethodCall & call)
+ : UnsubscribeMethodCall(call.interfaceName)
+ {
+ sourceUuid = call.sourceUuid;
+ zone = call.zone;
+ }
+
+ UnsubscribeMethodCall(const std::string & ifaceName)
+ :MethodCall("unsubscribe"), interfaceName(ifaceName)
+ {
+
+ }
+
+ static bool is(const BaseMessage *msg)
+ {
+ return msg->name == "unsubscribe";
+ }
+
+ static bool is(const picojson::value & json)
+ {
+ return json.get("name").to_str() == "unsubscribe";
+ }
+
+ std::string interfaceName;
+};
+
+class TimeSyncMessage : public BaseMessage
+{
+public:
+ TimeSyncMessage()
+ :BaseMessage("timeSync", "message"), serverTime(0)
+ {
+
+ }
+
+ double serverTime;
+
+ picojson::value toJson();
+ bool fromJson(const picojson::value &json);
+
+ static bool is(const BaseMessage & msg)
+ {
+ return msg.type == "timeSync" && msg.name == "message";
}
- Object value;
+ static bool is(const picojson::value &json)
+ {
+ return json.contains("serverTime") && json.get("type").to_str() == "timeSync" && json.get("serverTime").is<double>();
+ }
};
class BaseJsonMessageReader
};
+
+typedef std::shared_ptr<ListMethodCall> ListMethodCallPtr;
+typedef std::shared_ptr<GetMethodCall> GetMethodCallPtr;
+typedef std::shared_ptr<SetMethodCall> SetMethodCallPtr;
+typedef std::shared_ptr<SubscribeMethodCall> SubscribeMethodCallPtr;
+typedef std::shared_ptr<UnsubscribeMethodCall> UnsubscribeMethodCallPtr;
+typedef std::shared_ptr<TimeSyncMessage> TimeSyncMessagePtr;
+
class AmbRemoteClient: public BaseJsonMessageReader
{
public:
- typedef std::function<void (std::vector<Object>)> ListCallback;
- typedef std::function<void (Object&)> ObjectCallback;
+ typedef std::function<void (std::vector<Object::ObjectPtr>)> ListCallback;
+ typedef std::function<void (Object::ObjectPtr)> ObjectCallback;
typedef std::function<void (bool)> SetCallback;
+ class Subscription
+ {
+ public:
+ Subscription(SubscribeMethodCall subscribeCall, const ObjectCallback & cb)
+ :call(subscribeCall), callback(cb) {}
+ bool operator ==(const Subscription &rhs)
+ {
+ return rhs.subscriptionId() == subscriptionId();
+ }
+
+ const std::string subscriptionId() const { return call.messageId; }
+ SubscribeMethodCall call;
+ AmbRemoteClient::ObjectCallback callback;
+ };
+
AmbRemoteClient(AbstractIo* io);
void list(ListCallback cb);
void get(const std::string & objectName, const std::string & sourceUuid, Zone::Type zone, ObjectCallback cb);
- void set(const std::string & objectName, const Object & value, SetCallback cb);
+ void set(const std::string & objectName, Object::ObjectPtr value, SetCallback cb);
+
+ void set(const std::string & objectName, Object::ObjectPtr value, const std::string & sourceUuid, Zone::Type zone, SetCallback cb);
- void set(const std::string & objectName, const Object & value, const std::string & sourceUuid, Zone::Type zone, SetCallback cb);
+ const std::string subscribe(const std::string & objectName, const std::string & sourceUuid, Zone::Type zone, ObjectCallback cb);
- void listen(const std::string & objectName, const std::string & sourceUuid, Zone::Type zone, ObjectCallback cb);
+ void subscribe(const std::string & objectName, ObjectCallback cb);
- void listen(const std::string & objectName, ObjectCallback cb);
+ void unsubscribe(const std::string & subscribeId);
protected:
+ double correctedTime();
+
private:
void hasJsonMessage(const picojson::value & message);
std::unordered_map<std::string, ListCallback> mListCalls;
std::unordered_map<std::string, ObjectCallback> mGetMethodCalls;
std::unordered_map<std::string, SetCallback> mSetMethodCalls;
- std::unordered_map<std::string, std::vector<ObjectCallback>> mSubsriptions;
+ std::unordered_map<std::string, std::vector<Subscription>> mSubscriptions;
+
+ double serverTimeOffset;
};
class AmbRemoteServer : public BaseJsonMessageReader
/*!
* \brief list called when a ListMessageCall was received
*/
- virtual void list(ListMethodCall & call);
+ virtual void list(ListMethodCallPtr call);
/*!
* \brief get called when a GetMessageCall was received
*/
- virtual void get(GetMethodCall &get);
+ virtual void get(GetMethodCallPtr get);
/*!
* \brief set called when SetMessageCall was received
*/
- virtual void set();
+ virtual void set(SetMethodCallPtr set);
/*!
* \brief listen called when ListenMessageCall was received
*/
- virtual void listen();
+ virtual void subscribe(SubscribeMethodCallPtr call);
+
+ virtual void unsubscribe(UnsubscribeMethodCallPtr call);
void hasJsonMessage(const picojson::value & json);
class Server : public amb::AmbRemoteServer
{
public:
- Server(QLocalSocket* socketConnection): amb::AmbRemoteServer(new DomainSocket(socketConnection), nullptr) {}
+ Server(QLocalSocket* socketConnection)
+ : amb::AmbRemoteServer(new DomainSocket(socketConnection), nullptr),
+ speed(100), engineSpeed(1999)
+ {}
// AmbRemoteServer interface
protected:
- void list(amb::ListMethodCall &call)
+ void list(amb::ListMethodCallPtr call)
{
DebugOut(0) << "list called" << endl;
- amb::Object interface1("interface1");
- amb::Object interface2("interface2");
+ amb::Object::ObjectPtr interface1(new amb::Object("interface1"));
+ amb::Object::ObjectPtr interface2( new amb::Object("interface2"));
- interface1.emplace("vehicleSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::VehicleSpeedType(100)));
- interface1.emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(1999)));
+ interface1->emplace("vehicleSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::VehicleSpeedType(speed)));
+ interface1->emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(engineSpeed)));
- interface2.emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(3099)));
+ interface2->emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(3099)));
- call.objectNames.push_back(interface1);
- call.objectNames.push_back(interface2);
- call.success = true;
+ call->objectNames.push_back(interface1);
+ call->objectNames.push_back(interface2);
+ amb::MethodReply<amb::ListMethodCall> reply(call, true);
- send(call);
+ send(reply);
}
- void get(amb::GetMethodCall &get)
+ void get(amb::GetMethodCallPtr get)
{
DebugOut(0) << "get called" << endl;
- if(get.value.interfaceName == "interface1")
+ if(get->value->interfaceName == "interface1")
{
- amb::Object interface1("interface1");
+ amb::Object::ObjectPtr interface1(new amb::Object("interface1"));
- interface1.emplace("vehicleSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::VehicleSpeedType(100)));
- interface1.emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(1999)));
- get.value = interface1;
+ interface1->emplace("vehicleSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::VehicleSpeedType(100)));
+ interface1->emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(1999)));
+ get->value = interface1;
+ amb::MethodReply<amb::GetMethodCall> reply(get, true);
+ send(reply);
}
- else if(get.value.interfaceName == "interface2")
+ else if(get->value->interfaceName == "interface2")
{
- amb::Object interface2("interface2");
- interface2.emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(3099)));
- get.value = interface2;
+ amb::Object::ObjectPtr interface2(new amb::Object("interface2"));
+ interface2->emplace("engineSpeed", std::shared_ptr<AbstractPropertyType>(new VehicleProperty::EngineSpeedType(3099)));
+ get->value = interface2;
+ amb::MethodReply<amb::GetMethodCall> reply(get, true);
+ send(reply);
}
+ }
+ void set(amb::SetMethodCallPtr set)
+ {
+ if(set->value->interfaceName == "interface1")
+ {
+ speed = set->value->at("vehicleSpeed")->value<uint16_t>();
- send(get);
+ DebugOut(0) << "Speed set to " << speed << endl;
+ amb::MethodReply<amb::SetMethodCall> reply (set, true);
+ send(reply);
+ }
+ else
+ {
+ amb::MethodReply<amb::SetMethodCall> reply (set, false);
+ send(reply);
+ }
}
+
+ uint16_t speed;
+ uint16_t engineSpeed;
};
int main(int argc, char** argv)
void runTest(amb::AmbRemoteClient *c)
{
DebugOut(0) << "calling client->list()" << endl;
- c->list([](std::vector<amb::Object> supported)
+ c->list([](std::vector<amb::Object::ObjectPtr> supported)
{
DebugOut(0) << "list call reply" << endl;
g_assert(supported.size() == 2);
});
DebugOut(0) << "calling client->get()" << endl;
- c->get("interface1", [](amb::Object &obj)
+ c->get("interface1", [&c](amb::Object::ObjectPtr obj)
{
DebugOut(0) << "get call reply" << endl;
- g_assert(obj.size() == 2);
+ g_assert(obj->size() == 2);
+
+ obj->emplace("vehicleSpeed", amb::make_shared(new VehicleProperty::VehicleSpeedType(69)));
+
+ c->set("interface1", obj, [](bool s)
+ {
+ DebugOut(0) << "set call reply status: " << (s ? "success!" : "fail") << endl;
+ g_assert(s);
+ });
});
}