1 /*****************************************************************
2 Copyright (C) 2014 Intel Corporation
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 *****************************************************************/
19 #include <boost/assert.hpp>
23 #include <vehicleproperty.h>
24 #include <listplusplus.h>
28 #include "ambtmpl_plugin.h"
29 #include "ambtmpl_cansignals.h"
31 //using namespace AmbTmplPlugin;
33 static const char* DEFAULT_CAN_IF_NAME = "vcan0";
35 // library exported function for plugin loader
36 extern "C" AbstractSource * create(AbstractRoutingEngine* routingengine, std::map<std::string, std::string> config)
39 DEBUG_CONF("AmbTmplPlugin",
40 CUtil::Logger::file_off|CUtil::Logger::screen_on,
41 CUtil::Logger::EInfo, CUtil::Logger::EInfo
45 std::unique_ptr< AmbPlugin<AmbTmplPlugin> > plugin(new AmbPlugin<AmbTmplPlugin>(routingengine, config));
47 return plugin.release();
50 void AmbTmplPlugin::timerDestroyNotify(gpointer data)
52 TimerData* timerData = reinterpret_cast<TimerData*>(data);
54 AmbTmplPlugin* plugin = std::get<0>(*timerData);
55 const can_frame& frame = std::get<3>(*timerData);
56 plugin->eraseTimer(frame.can_id);
62 gboolean AmbTmplPlugin::timeoutCallback(gpointer data)
64 TimerData* timerData = reinterpret_cast<TimerData*>(data);
68 CANBus* bus = std::get<1>(*timerData);
69 int retries = --std::get<2>(*timerData);
70 const can_frame& frame = std::get<3>(*timerData);
74 bus->sendStandardFrame(frame);
80 //----------------------------------------------------------------------------
82 //----------------------------------------------------------------------------
84 AmbTmplPlugin::AmbTmplPlugin(AbstractRoutingEngine* re, const map<string, string>& config, AbstractSource& parent) :
85 AmbPluginImpl(re, config, parent),
86 interface(DEFAULT_CAN_IF_NAME),
87 canBus(new CANBus(*static_cast<CANObserver*>(this))),
88 announcementIntervalTimer(1000),
91 auto it = config.find("interface");
92 if (it != config.end() && it->second.length())
93 interface = it->second;
95 it = config.find("announcementIntervalTimer");
96 if (it != config.end() && it->second.length())
97 announcementIntervalTimer = atoi(std::string(it->second).c_str());
98 if(announcementIntervalTimer < 20)
99 announcementIntervalTimer = 20;
101 it = config.find("announcementCount");
102 if (it != config.end() && it->second.length())
103 announcementCount = atoi(std::string(it->second).c_str());
104 if(announcementCount < 1)
105 announcementIntervalTimer = 1;
110 AmbTmplPlugin::~AmbTmplPlugin()
112 std::list<guint> timerList;
115 for(auto it=timers.begin();it!=timers.end();++it)
116 timerList.push_back(it->second);
119 for(auto it=timerList.begin();it!=timerList.end();++it)
120 g_source_remove(*it);
125 void AmbTmplPlugin::init()
127 canBus->start(interface.c_str());
130 AsyncPropertyReply *AmbTmplPlugin::setProperty(const AsyncSetPropertyRequest& request )
132 AsyncPropertyReply* reply = new AsyncPropertyReply(request);
133 reply->success = false;
134 reply->error = AsyncPropertyReply::InvalidOperation;
136 AbstractPropertyType *value = findPropertyType(request.property, request.zoneFilter);
137 if (value && request.value) {
138 DebugOut(2) << "updating property "<< request.property << " to: " << request.value->toString() << endl;
140 std::unique_ptr<GVariant, decltype(&g_variant_unref)> variant(request.value->toVariant(), &g_variant_unref);
141 value->fromVariant(variant.get());
143 if(sendValue(request.value)) {
144 DebugOut(2) << "New value of property "<< request.property << " is: " << value->toString() << endl;
145 value->timestamp = amb::currentTime();
146 routingEngine->updateProperty(value, uuid());
148 reply->success = true;
149 reply->error = AsyncPropertyReply::NoError;
155 reply->completed(reply);
162 int AmbTmplPlugin::supportedOperations() const
164 return AbstractSource::Get | AbstractSource::Set;
167 void AmbTmplPlugin::onMessage(const can_frame& frame)
169 auto messageIt = messages.find(frame.can_id);
170 if(messageIt == messages.end())
173 CANMessage& message(messageIt->second);
174 const std::string guid = uuid();
175 AbstractRoutingEngine* re = routingEngine;
176 message.onMessage( frame, [&re, &guid](AbstractPropertyType* value){re->updateProperty(value, guid);} );
179 bool AmbTmplPlugin::sendValue(AbstractPropertyType* value)
184 auto it = propertyToMessage.find(value->name);
185 if(it == propertyToMessage.end())
188 CANMessage* canMessage = it->second;
190 canMessage->setupFrame(&frame);
191 return sendStandardFrame(frame);
195 void AmbTmplPlugin::errorOccured(CANObserver::CANError error)
198 LOG_INFO( "AmbTmplPlugin::errorOccured() not implemented "<< std::endl );
201 void AmbTmplPlugin::standardFrameReceived(const can_frame& frame)
203 LOG_INFO("AmbTmplPlugin::standardFrameReceived()");
209 void AmbTmplPlugin::extendedFrameReceived(const can_frame& frame)
211 LOG_INFO("AmbTmplPlugin::extendedFrameReceived()");
217 void AmbTmplPlugin::errorFrameReceived(const can_frame& frame)
219 LOG_INFO("AmbTmplPlugin::errorFrameReceived()");
223 void AmbTmplPlugin::remoteTransmissionRequest(const can_frame& frame)
226 LOG_INFO( "AmbTmplPlugin::remoteTransmissionRequest() not implemented "<< std::endl );
229 bool AmbTmplPlugin::sendStandardFrame(const can_frame& frame)
233 auto it = timers.find(frame.can_id);
234 if(it != timers.end()){
235 oldTimer = it->second;
241 g_source_remove(oldTimer);
243 if ( canBus->sendStandardFrame(frame) ) {
244 LOG_TRACE( "AmbTmplPlugin::sendStandardFrame() success "<< std::endl );
245 scoped_lock<interprocess_recursive_mutex> lock(mutex);
246 std::unique_ptr< TimerData > timerData(new TimerData(this, canBus.get(), announcementCount, frame));
247 guint timer = g_timeout_add_full(G_PRIORITY_HIGH, announcementIntervalTimer, timeoutCallback, timerData.get(), timerDestroyNotify);
249 timers[frame.can_id] = timer;
255 LOG_WARNING( "AmbTmplPlugin::sendStandardFrame() failed "<< std::endl );
260 bool AmbTmplPlugin::sendExtendedFrame(const can_frame& frame)
262 if ( canBus->sendExtendedFrame(frame) ) {
263 LOG_TRACE( "AmbTmplPlugin::sendExtendedFrame() success "<< std::endl );
267 LOG_WARNING( "AmbTmplPlugin::sendExtendedFrame() failed "<< std::endl );
272 void AmbTmplPlugin::printFrame(const can_frame& frame) const
274 LOG_INFO( "AmbTmplPlugin::printFrame can_id: " << std::hex << frame.can_id << std::dec );
275 LOG_INFO( "AmbTmplPlugin::printFrame can_dlc: " << int(frame.can_dlc) );
277 std::stringstream ss;
278 for(int i=0; i<frame.can_dlc; ++i){
279 ss << " " << std::hex << (int)(frame.data[i]);
283 LOG_INFO( "AmbTmplPlugin::printFrame can data" << ss.str() );
286 void AmbTmplPlugin::registerMessages()