source: trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.hxx@ 9488

Last change on this file since 9488 was 1054, checked in by casaldaliga, 23 years ago
changed .H to .hxx in includes to work with new naming
File size: 9.4 KB
Line 
1#ifndef SUBSYSTEM
2#define SUBSYSTEM
3
4#include "PeriodicAction.hxx"
5#include "TCPListener.hxx"
6#include "IONotifier.hxx"
7#include "PeriodicAction.hxx"
8#include "TCPSender.hxx"
9#define TIMESTAMP_LEN 12
10//%02.2d:%02.2d:%02.2d:%03.3d
11//in Makefile#define MAXMSG 4096
12/**
13 * Base class for MAGIC Subsystem's communication with CC
14 *
15 * It implements commandListener (see MAGIC-TDAS 00-07) as a TCPListener
16 * derived class, to be able to custom the behaviour by overriding its
17 * methods
18 *
19 * Missing properties: Special Report in a GenerateSpecialReport method, also
20 * a final implementation of CheckReportAcknowledge (CC sends back
21 * "RECV:timestamp", with timestamp the one extracted from subsystem
22 * report. So subsystem has to have a member lastReportTimestamp to compare).
23 * Timeout in CheckReportAcknowledge?????.
24 *
25 * @short Base class for MAGIC Subsystem's communication with CC
26 * @author Marc Casaldaliga
27 * @version 0.9
28 * @see TCPListener
29 */
30class Subsystem: public TCPListener
31{
32
33public:
34
35 /**
36 * Set the string to be sent in the next report that will be sent to
37 * CC (with timestamp but without protocol specific item,
38 * e.g. trailing \n). The timestamp is the data one, the time when
39 * data was taken (the relevant for analysis), nothing to do with the
40 * the time the report will be sent.
41 *
42 * It takes care internally of suspending and resuming communications
43 * not to send something is being modified etc
44 *
45 * @param report CString with pure report (without "\n" ...)
46 */
47 void SetReportString(char * report);
48
49 /**
50 * Class unique constructor with the parameters which specify
51 * Subsystem configuration.
52 *
53 * @param portCommandListener TCP/IP port Subsystem will open to
54 * listen to cc commands
55 *
56 * @param reportPeriod Aproximate (+- 500ms) time in microsec,
57 * between each report is sent to CC
58 *
59 * @param ccName C string with CC machine name
60 *
61 * @param portReportListener TCP/IP port opened in CC which Subsystem
62 * will contact to send reports
63 *
64 * @param maxTimeoutCount_. Times subsystem tries to reconnect CC
65 * (with reportPeriod) periodicity, before it considers CC not
66 * available. After this count is reached Subsystem has to react some
67 * way (parking itself, ...). This is done by
68 * Subsystem::HandleConnectionTimeoutIsOver
69 *
70 * @see #HandleConnectionTimeoutIsOver
71 *
72 */
73 Subsystem (unsigned short int portCommandListener, unsigned long int
74 reportPeriod, char * ccName, unsigned short int
75 portReportListener, unsigned short int maxTimeoutCount_ );
76
77 /**
78 * Send (immediately) a special report which a part from
79 * protocol specific items (e.g. trailing \n and special report
80 * identifier) contains the argument specialReport
81 *
82 * ??? timestamp ????
83 *
84 * It takes care internally of suspending and resuming communications
85 * not to send something is being modified etc
86 *
87 * @param specialReport CString with pure special report (without
88 * "\n" ...)
89 *
90 * @return Returns whether sending will be succesful (true) or not
91 * (false)
92 */
93 bool SendSpecialReportContaining(char * specialReport);
94
95protected:
96 /**
97 * Field with the report that will be sent to CC (with timestamp but
98 * without protocol specific item, e.g. trailing \n)
99 *
100 * To be modified only within GenerateReport
101 */
102 char reportString[MAXMSG];
103
104 /** To be overriden. It has to do all the job of interpreting CC
105 * commands: (not the ones
106 * regarding starting connection, locking ...) but the ones for the
107 * subsystem function (This way we separate the protocol dependent
108 * stuff).
109 *
110 * Compares Subsystem::ccCmd with known commands from cc and executes
111 * the appropiate function
112 *
113 * This method is automatically called when a command from cc is
114 * received, after checking it is not a communication/locking command
115 *
116 * If receiving a nonsense command call to ResetConnectionToCC()
117 * (Network partner it's not -a properly working- CC). In principle
118 * this will close and open again, but let's leave it this way so that
119 * it is not protocol dependent
120 *
121 * @param ccCmd CString with pure CC command (without "\n" ...)
122 */
123 virtual void ProcessCmd(char *ccCmd);
124
125 /** GenerateReport (to be overriden) This next method is automatically
126 * called before sending a report.
127 *
128 * According to state and data this should write
129 * Subsystem::reportString (it
130 * should include the timestamp of the data sent, but without any
131 * trailing \n--this is part of the protocol)
132 *
133 * After it, this Subsystem::reportString plus any protocol dependent
134 * thing is sent. This GenerateReport and send is periodically
135 * repeated with reportPeriod
136 *
137 * Alternatively, one may leave GenerateReport empty and from outside
138 * call to Subsystem::SetReportString when hardware info is updated
139 * (probably what one what like to do).
140 */
141 virtual void GenerateReport();
142
143 /** HandleConnectionTimeoutIsOver. Does what the subsystem is suposed
144 * to do when it has lost definitely connection to CC. To be
145 * overriden.
146 *
147 * After Subsystem::maxTimeoutCount times of reconnection tries CC is
148 * considered not available. Subsystem has to react some way (parking
149 * itself, ... ) depending on its autonomy. This is done by
150 * overriding this method with the desired behaviour.
151 *
152 * After HandleConnectionTimeoutIsOver is done Subsystem will listen
153 * to CC again and start all communication process.
154 *
155 * see #maxTimeoutCount
156 */
157 virtual void HandleConnectionTimeoutIsOver();
158
159 /** SuspendComm. Suspend communication threads
160 *
161 * To prevent Subsystem to access its resources (e.g. send
162 * reportString) when we are about to access them externally (fill
163 * reportString with actual data), one can call to this method and
164 * suspend subsystem activity.
165 * To resume it call to Subsystem::ResumeComm.
166 *
167 * Always paired with a ResumeComm.
168 *
169 * If Subsystem is at that time accessing the resources, SuspendComm
170 * will wait for them to be released and then will lock them.
171 *
172 * @see #ResumeComm
173 *
174 */
175 void SuspendComm();
176
177 /** ResumeComm. Resume communication threads
178 *
179 * After calling SuspendComm() and having access to Subsystem
180 * resources (e.g. fill reportString with actual data) allow
181 * Subsystem to access them again and resume it's activity. we are
182 * about to access them externally (fill reportString with actual
183 * data), one can call to this method and suspend subsystem activity.
184 *
185 * @see #SuspendComm
186 *
187 */
188 void ResumeComm();
189
190 /**
191 * Resets communication to CC, to be used when a nonsense command
192 * arrives from CC
193 * @see #ProcessCmd
194 */
195 void ResetConnectionToCC();
196
197
198
199private:
200 /**
201 * C string with CC machine name
202 */
203 char* ccName;
204 /**
205 * Aproximate (+- 500ms) time in microsec, between each report is sent
206 * to CC
207 */
208 unsigned long reportPeriod;
209
210 unsigned short int portCommandListener;
211 unsigned short int portReportListener;
212
213 //we implement commandListener as a TCPListener derived class, to be
214 //able to custom the behaviour by overriding it's methods, namely
215 //process
216
217 /* maxTimeoutCount. Times subsystem tries to reconnect CC (with reportPeriod)
218 * periodicity, before it considers CC not available.
219 *
220 * After this count is reached Subsystem has to react some way
221 * (parking itself, ...). This is done by
222 * Subsystem::HandleConnectionTimeoutIsOver
223 *
224 * @see #HandleConnectionTimeoutIsOver
225 *
226 */
227
228 short int maxTimeoutCount;
229
230
231 bool locked;
232 bool reporting;
233 IONotifier* reportAckNotifier;
234
235 //we implement reportSender as an instance of class TCPSender
236 TCPSender reportSender;
237 //reporting and trying connections to cc are implemented as
238 //PeriodicActions
239 PeriodicAction tryReportConn,reportingLoop;
240 pthread_mutex_t mutex4report;
241 inline void StartReporting();
242 virtual void process();
243 bool SendReport();
244 void CheckReportAcknowledge();
245 //to be able to checkreportacknowledge on has to have the timestamp of
246 //the last report sent
247 char lastTimeStamp[TIMESTAMP_LEN];
248 void ExtractTimeStampFromLastReportTo(char *);
249
250 bool acknowledgeReceivedForLastReport;
251 short int timeoutCount;
252 pthread_mutex_t mutex4ack;
253 void Lock();
254 void ULock();
255
256};
257
258#endif
Note: See TracBrowser for help on using the repository browser.