blob: 6c7e293d12505dd8f7a2710a4973fff02a1b2d4e [file] [log] [blame]
Ernesto Posse8a4f2962015-05-12 13:28:46 -04001// umlrttimerprotocol.cc
2
3/*******************************************************************************
4* Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others.
5* All rights reserved. This program and the accompanying materials
6* are made available under the terms of the Eclipse Public License v1.0
7* which accompanies this distribution, and is available at
8* http://www.eclipse.org/legal/epl-v10.html
9*******************************************************************************/
10
11#include "umlrtslot.hh"
12#include "umlrtcommsport.hh"
13#include "umlrtcommsportrole.hh"
14#include "umlrtcontroller.hh"
15#include "umlrttimerprotocol.hh"
16#include "umlrttimer.hh"
17#include "umlrttimerid.hh"
18#include "umlrtapi.hh"
19#include "basefatal.hh"
20#include "basedebugtype.hh"
21#include "basedebug.hh"
22#include <stdlib.h>
23
24// Protocol implementation for timer ports.
25
26// Allocate a timer.
27/*static*/ UMLRTTimerId UMLRTTimerProtocol::allocateTimer( const UMLRTCommsPort * srcPort, bool isRelative, bool isInterval, const UMLRTTimespec & due,
28 UMLRTSignalElement::Priority priority, const void * userData, const UMLRTObject_class * type )
29{
30 UMLRTTimer * timer = umlrt::TimerGetFromPool();
31
32 if (!timer)
33 {
34 srcPort->slot->controller->setError(UMLRTController::E_TIMER_GET);
35 }
36 else if (!timer->allocated)
37 {
38 FATAL("allocated timer not deemed allocated.");
39 }
40 else
41 {
42 if (isRelative)
43 {
44 UMLRTTimespec now;
45 UMLRTTimespec::getClock(&now);
46 timer->due = now + due;
47 }
48 else
49 {
50 timer->due = due;
51 }
52 timer->isInterval = isInterval;
53 if (isInterval)
54 {
55 timer->interval = due;
56 }
57 timer->destPort = srcPort;
58 timer->destSlot = srcPort->slot;
59
60 size_t payloadSize = 0;
61 if (userData)
62 {
63 if (!type)
64 {
65 FATAL("user data requires a type descriptor");
66 }
67 payloadSize = type->getSize(type);
68 }
69 timer->signal.initialize(UMLRTTimerProtocol::signal_timeout, srcPort, payloadSize, priority);
70
71 char buf[UMLRTTimespec::TIMESPEC_TOSTRING_SZ];
72
73 BDEBUG(BD_TIMER, "allocate timer(%p) destPort(%s) isInterval(%d) priority(%d) payloadSize(%d) due(%s)\n",
74 timer, timer->destPort->role()->name, timer->isInterval, timer->signal.getPriority(), timer->signal.getPayloadSize(),
75 timer->isInterval ? timer->due.toStringRelative(buf, sizeof(buf)) : timer->due.toString(buf, sizeof(buf)));
76
77 if (userData)
78 {
79 timer->signal.encode(userData, type);
80 }
81 }
82 return UMLRTTimerId(timer);
83}
84
85const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informAt( const UMLRTCommsPort * srcPort, const UMLRTTimespec & clockTime, UMLRTSignalElement::Priority priority ) const
86{
87 UMLRTTimerId id = allocateTimer(srcPort, false, false, clockTime, priority, NULL, NULL);
88
89 if (id.isValid())
90 {
91 // Pass the timer to the controller to monitor it.
92 srcPort->slot->controller->startTimer(id.getTimer());
93 }
94 return id;
95}
96const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informAt( const UMLRTCommsPort * srcPort, const UMLRTTimespec & clockTime, const void * userData, const UMLRTObject_class * type, UMLRTSignalElement::Priority priority ) const
97{
98 UMLRTTimerId id = allocateTimer(srcPort, false, false, clockTime, priority, userData, type);
99
100 if (id.isValid())
101 {
102 // Pass the timer to the controller to monitor it.
103 srcPort->slot->controller->startTimer(id.getTimer());
104 }
105 return id;
106}
107const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informAt( const UMLRTCommsPort * srcPort, const UMLRTTimespec & clockTime, const UMLRTTypedValue & typedValue, UMLRTSignalElement::Priority priority ) const
108{
109 UMLRTTimerId id = allocateTimer(srcPort, false, false, clockTime, priority, typedValue.data, typedValue.type);
110
111 if (id.isValid())
112 {
113 // Pass the timer to the controller to monitor it.
114 srcPort->slot->controller->startTimer(id.getTimer());
115 }
116 return id;
117}
118
119const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informIn( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, UMLRTSignalElement::Priority priority ) const
120{
121 UMLRTTimerId id = allocateTimer(srcPort, true, false, relativeTime, priority, NULL, NULL);
122
123 if (id.isValid())
124 {
125 // Pass the timer to the controller to monitor it.
126 srcPort->slot->controller->startTimer(id.getTimer());
127 }
128 return id;
129}
130const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informIn( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, void * userData, const UMLRTObject_class * type, UMLRTSignalElement::Priority priority ) const
131{
132 UMLRTTimerId id = allocateTimer(srcPort, true, false, relativeTime, priority, userData, type);
133
134 if (id.isValid())
135 {
136 // Pass the timer to the controller to monitor it.
137 srcPort->slot->controller->startTimer(id.getTimer());
138 }
139 return id;
140}
141const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informIn( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, const UMLRTTypedValue & typedValue, UMLRTSignalElement::Priority priority ) const
142{
143 UMLRTTimerId id = allocateTimer(srcPort, true, false, relativeTime, priority, typedValue.data, typedValue.type);
144
145 if (id.isValid())
146 {
147 // Pass the timer to the controller to monitor it.
148 srcPort->slot->controller->startTimer(id.getTimer());
149 }
150 return id;
151}
152
153const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informEvery( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, UMLRTSignalElement::Priority priority ) const
154{
155 UMLRTTimerId id = allocateTimer(srcPort, true, true, relativeTime, priority, NULL, NULL);
156
157 if (id.isValid())
158 {
159 // Pass the timer to the controller to monitor it.
160 srcPort->slot->controller->startTimer(id.getTimer());
161 }
162 return id;
163}
164const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informEvery( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, void * userData, const UMLRTObject_class * type, UMLRTSignalElement::Priority priority ) const
165{
166 UMLRTTimerId id = allocateTimer(srcPort, true, true, relativeTime, priority, userData, type);
167
168 if (id.isValid())
169 {
170 // Pass the timer to the controller to monitor it.
171 srcPort->slot->controller->startTimer(id.getTimer());
172 }
173 return id;
174}
175const UMLRTTimerId UMLRTTimerProtocol::OutSignals::informEvery( const UMLRTCommsPort * srcPort, const UMLRTTimespec & relativeTime, const UMLRTTypedValue & typedValue, UMLRTSignalElement::Priority priority ) const
176{
177 UMLRTTimerId id = allocateTimer(srcPort, true, true, relativeTime, priority, typedValue.data, typedValue.type);
178
179 if (id.isValid())
180 {
181 // Pass the timer to the controller to monitor it.
182 srcPort->slot->controller->startTimer(id.getTimer());
183 }
184 return id;
185}
186
187bool UMLRTTimerProtocol::OutSignals::cancelTimer( const UMLRTCommsPort * srcPort, const UMLRTTimerId id ) const
188{
189 if (!id.isValid())
190 {
191 srcPort->slot->controller->setError(UMLRTController::E_TIMER_CANC_INV);
192 return false;
193 }
194 return srcPort->slot->controller->cancelTimer(id);
195}
196
197void UMLRTTimerProtocol::OutSignals::timeAdjustStart( const UMLRTCommsPort * srcPort ) const
198{
199 FATAL("timer adjust start not implemented");
200}
201void UMLRTTimerProtocol::OutSignals::timeAdjustComplete(const UMLRTCommsPort * srcPort, const UMLRTTimespec & delta ) const
202{
203 FATAL("timer adjust complete not implemented");
204}