blob: 6c7e293d12505dd8f7a2710a4973fff02a1b2d4e [file] [log] [blame]
// umlrttimerprotocol.cc
/*******************************************************************************
* Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
#include "umlrtslot.hh"
#include "umlrtcommsport.hh"
#include "umlrtcommsportrole.hh"
#include "umlrtcontroller.hh"
#include "umlrttimerprotocol.hh"
#include "umlrttimer.hh"
#include "umlrttimerid.hh"
#include "umlrtapi.hh"
#include "basefatal.hh"
#include "basedebugtype.hh"
#include "basedebug.hh"
#include <stdlib.h>
// Protocol implementation for timer ports.
// Allocate a timer.
/*static*/ UMLRTTimerId UMLRTTimerProtocol::allocateTimer( const UMLRTCommsPort * srcPort, bool isRelative, bool isInterval, const UMLRTTimespec & due,
UMLRTSignalElement::Priority priority, const void * userData, const UMLRTObject_class * type )
{
UMLRTTimer * timer = umlrt::TimerGetFromPool();
if (!timer)
{
srcPort->slot->controller->setError(UMLRTController::E_TIMER_GET);
}
else if (!timer->allocated)
{
FATAL("allocated timer not deemed allocated.");
}
else
{
if (isRelative)
{
UMLRTTimespec now;
UMLRTTimespec::getClock(&now);
timer->due = now + due;
}
else
{
timer->due = due;
}
timer->isInterval = isInterval;
if (isInterval)
{
timer->interval = due;
}
timer->destPort = srcPort;
timer->destSlot = srcPort->slot;
size_t payloadSize = 0;
if (userData)
{
if (!type)
{
FATAL("user data requires a type descriptor");
}
payloadSize = type->getSize(type);
}
timer->signal.initialize(UMLRTTimerProtocol::signal_timeout, srcPort, payloadSize, priority);
char buf[UMLRTTimespec::TIMESPEC_TOSTRING_SZ];
BDEBUG(BD_TIMER, "allocate timer(%p) destPort(%s) isInterval(%d) priority(%d) payloadSize(%d) due(%s)\n",
timer, timer->destPort->role()->name, timer->isInterval, timer->signal.getPriority(), timer->signal.getPayloadSize(),
timer->isInterval ? timer->due.toStringRelative(buf, sizeof(buf)) : timer->due.toString(buf, sizeof(buf)));
if (userData)
{
timer->signal.encode(userData, type);
}
}
return UMLRTTimerId(timer);
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informAt( const UMLRTCommsPort * srcPort, const UMLRTTimespec & clockTime, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, false, false, clockTime, priority, NULL, NULL);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informAt( const UMLRTCommsPort * srcPort, const UMLRTTimespec & clockTime, const void * userData, const UMLRTObject_class * type, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, false, false, clockTime, priority, userData, type);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informAt( const UMLRTCommsPort * srcPort, const UMLRTTimespec & clockTime, const UMLRTTypedValue & typedValue, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, false, false, clockTime, priority, typedValue.data, typedValue.type);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informIn( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, true, false, relativeTime, priority, NULL, NULL);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informIn( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, void * userData, const UMLRTObject_class * type, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, true, false, relativeTime, priority, userData, type);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informIn( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, const UMLRTTypedValue & typedValue, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, true, false, relativeTime, priority, typedValue.data, typedValue.type);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informEvery( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, true, true, relativeTime, priority, NULL, NULL);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informEvery( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, void * userData, const UMLRTObject_class * type, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, true, true, relativeTime, priority, userData, type);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informEvery( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, const UMLRTTypedValue & typedValue, UMLRTSignalElement::Priority priority ) const
{
UMLRTTimerId id = allocateTimer(srcPort, true, true, relativeTime, priority, typedValue.data, typedValue.type);
if (id.isValid())
{
// Pass the timer to the controller to monitor it.
srcPort->slot->controller->startTimer(id.getTimer());
}
return id;
}
bool UMLRTTimerProtocol::OutSignals::cancelTimer( const UMLRTCommsPort * srcPort, const UMLRTTimerId id ) const
{
if (!id.isValid())
{
srcPort->slot->controller->setError(UMLRTController::E_TIMER_CANC_INV);
return false;
}
return srcPort->slot->controller->cancelTimer(id);
}
void UMLRTTimerProtocol::OutSignals::timeAdjustStart( const UMLRTCommsPort * srcPort ) const
{
FATAL("timer adjust start not implemented");
}
void UMLRTTimerProtocol::OutSignals::timeAdjustComplete(const UMLRTCommsPort * srcPort, const UMLRTTimespec & delta ) const
{
FATAL("timer adjust complete not implemented");
}