File: ArServerHandlerConfig.h

package info (click to toggle)
libaria 2.8.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 13,628 kB
  • ctags: 16,574
  • sloc: cpp: 135,490; makefile: 925; python: 597; java: 570; ansic: 182
file content (321 lines) | stat: -rw-r--r-- 14,437 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#ifndef ARSERVERCONFIGHANDLER_H
#define ARSERVERCONFIGHANDLER_H

#include "Aria.h"
#include "ArServerBase.h"

class ArServerClient;

/// Class for sending and receiving ArConfig data via ArNetworking.
/**
 * ArServerHandlerConfig defines the network packet handlers used to transmit
 * ArConfig objects to a client, and to modify them based on information 
 * received from the client.  Since the packet structure for the ArConfig is 
 * rather complex, this class is best used in conjunction with the 
 * ArClientHandlerConfig.
 * 
 * This class handles the following requests:
 *  <ul>
 *    <li>getConfigBySections/getConfigBySectionsV2:  Replies with multiple 
 *        packets, one for each ArConfig section plus an empty packet that 
 *        terminates the reply.  Each packet contains the following header 
 *        information:
 *        <ol> 
 *          <li>Section Indicator: Always set to 'S' (byte)</li>
 *          <li>Section Name: (string)</li>
 *          <li>Section Comment: (string) </li>  
 *          <li>Section Category Name: (string) Only for getConfigBySectionsV2 </li>
 *        </ol>
 *        For each parameter in the section, the packet then contains a 
 *        a Parameter Indicator (always set to 'P' (byte)) followed by a 
 *        complete description of the parameter (display hints are included).  
 *        See ArClientArgUtils for more information.
 *    </li>
 *    <li>getConfig:  This request has been superceded by getConfigBySections. (It
 *        replies with a single packet containing all of the ArConfig 
 *        sections as described above.  If the ArConfig is large, then it 
 *        may not be sent successfully.  In addition, it contains no parameter
 *        display hints.)
 *    </li>
 *    <li>setConfig: Parses the received packet and updates the robot's 
 *        ArConfig (and saves it to the file).  For each modified section, 
 *        the received packet is expected to contain:
 *        <ol>
 *          <li>Section Indicator: Always set to "Section" (string)</li>
 *          <li>Section Name: (string) </li>
 *        </ol>
 *        Followed by a brief "text" description of each modified parameter.
 *        This is the parameter name (string) followed by the parameter value
 *        formatted as text (string).  See ArClientArgUtils for more information.
 *        
 *        A reply packet containing a string is sent to the client. If the 
 *        string is empty, then the config was successfully updated.  Otherwise,
 *        the string contains the name of the first parameter that caused an
 *        error during the update handling.
 *    </li>
 *    <li>reloadConfig: Reloads the ArConfig from the text file. 
 *    </li>
 *    <li>configUpdated: An empty packet is broadcast to all interested clients
 *        after setConfig or reloadConfig has been completed.  The clients may
 *        then request the modified ArConfig data with getConfigBySections
 *        (or getConfig).
 *    </li>
 *    <li>getConfigDefaults: If a "default" configuration file is available,
 *        then this command can be used to send the preferred default values
 *        to the client.  The received packet should contain a single string,
 *        which is the name of the section to be retrieved, or an empty string
 *        to indicate all sections.  
 *        
 *        For each requested section, the reply packet contains:
 *        <ol>
 *          <li>Section Indicator: Always set to "Section" (string)</li>
 *          <li>Section Name: (string) </li>
 *        </ol>
 *        Followed by a brief "text" description of each default parameter value.
 *        This is the parameter name (string) followed by the parameter value
 *        formatted as text (string).  See ArClientArgUtils for more information.
 *    </li>
 *  </ul>
 * 
 *  If you are using this class with the default file option you'll
 *  want to make it AFTER you're done adding things to the config, ie
 *  last, so that the default code can work correctly (it needs to know
 *  about all the info).
**/
class ArServerHandlerConfig
{
public:

  /// Constructor
  /**
   * @param server the ArServerBase * used to send and receive network packets;
   * must be non-NULL
   * @param config the ArConfig * that is maintained by this server handler
   * @param defaultFile the char * name of the file that contains the default
   * values for the ArConfig; if NULL, then getConfigDefaults will not be
   * supported
   * @param defaultFileBaseDirectory the char * name of the directory that
   * contains the default file
  **/
  AREXPORT ArServerHandlerConfig(ArServerBase *server, 
                                 ArConfig *config,
                                 const char *defaultFile = NULL, 
                                 const char *defaultFileBaseDirectory = NULL,
                                 bool allowFactory = true,
                                 const char *robotName = NULL,
                                 bool preventChanges = false,
                                 const char *preventChangesString = NULL);
  
  /// Destructor
  AREXPORT virtual ~ArServerHandlerConfig();

  // ---------------------------------------------------------------------------
  // Network Packet Handlers 
  // ---------------------------------------------------------------------------

  /// Handles the "reloadConfig" request.
  AREXPORT void reloadConfig(ArServerClient *client, ArNetPacket *packet);

  /// Handles the "getConfigBySections" request.
  AREXPORT void getConfigBySections(ArServerClient *client, ArNetPacket *packet);

  /// Handles the "getConfigBySectionsV2" request.
  AREXPORT void getConfigBySectionsV2(ArServerClient *client, ArNetPacket *packet);

  /// Handles the "getConfigBySectionsV3" request.
  AREXPORT void getConfigBySectionsV3(ArServerClient *client, ArNetPacket *packet);

  /// Handles the (deprecated) "getConfig" request.
  AREXPORT void getConfig(ArServerClient *client, ArNetPacket *packet);
  
  /// Handles the "setConfig" request.
  AREXPORT void setConfig(ArServerClient *client, ArNetPacket *packet);
  
  AREXPORT void setConfigBySections(ArServerClient *client, ArNetPacket *packet);
  
  AREXPORT void setConfigBySectionsV2(ArServerClient *client, ArNetPacket *packet);

  /// Handles the "getConfigDefaults" request.
  AREXPORT void getConfigDefaults(ArServerClient *client, ArNetPacket *packet);

  /// Handles the "getConfigSectionFlags" request.
  AREXPORT void getConfigSectionFlags(ArServerClient *client, 
				                              ArNetPacket *packet);

  /// Handles the "getLastEditablePriority" request.
  AREXPORT void getLastEditablePriority(ArServerClient *client,
                                        ArNetPacket *packet);

  // ---------------------------------------------------------------------------
  // Callback Methods
  // ---------------------------------------------------------------------------

  /// Adds a callback to be called before writing to disk
  AREXPORT void addPreWriteCallback(ArFunctor *functor, 
                                    ArListPos::Pos position = ArListPos::LAST);
  /// Removes a callback to be called before writing to disk
  AREXPORT void remPreWriteCallback(ArFunctor *functor);

  /// Adds a callback to be called after writing to disk
  AREXPORT void addPostWriteCallback(ArFunctor *functor, 
                                     ArListPos::Pos position = ArListPos::LAST);
  /// Removes a callback to be called after writing to disk
  AREXPORT void remPostWriteCallback(ArFunctor *functor);  

  /// Adds a callback to be called when the config is updated
  AREXPORT void addConfigUpdatedCallback(ArFunctor *functor, 
				                ArListPos::Pos position = ArListPos::LAST);
  /// Removes a callback to be called when the config is updated
  AREXPORT void remConfigUpdatedCallback(ArFunctor *functor);  

  /// Restarts the IO manually (mostly for because of a config change)
  void restartIO(const char *reason);
  /// Restarts the software manually (mostly for because of a config change)
  void restartSoftware(const char *reason);
  /// Restarts the hardware manually (mostly for because of a config change)
  void restartHardware(const char *reason);

  /// Adds a callback for when the IO is changed
  void addRestartIOCB(ArFunctor *functor, int position = 50) 
    { myRestartIOCBList.addCallback(functor, position); }
  /// Adds a callback for when the IO is changed
  void remRestartIOCB(ArFunctor *functor)
    { myRestartIOCBList.remCallback(functor); }

  /// Sets a callback for when a RESTART_SERVER config param is changed
  AREXPORT void setRestartSoftwareCB(ArFunctor *restartServerCB);

  /// Gets the callback for when a RESTART_SERVER config param is changed
  AREXPORT ArFunctor *getRestartSoftwareCB(void);

  /// Sets a callback for when a RESTART_ROBOT config param is changed
  AREXPORT void setRestartHardwareCB(ArFunctor *restartRobotCB);

  /// Gets the callback for when a RESTART_ROBOT config param is changed
  AREXPORT ArFunctor *getRestartHardwareCB(void);

  /// Locks the config so we don't do anything with it
  AREXPORT int lockConfig(void) { return myConfigMutex.lock(); }
  /// Tries to lock the config so we don't do anything with it
  AREXPORT int tryLockConfig(void) { return myConfigMutex.tryLock(); }
  /// Unlocks the config so we can use it again
  AREXPORT int unlockConfig(void) { return myConfigMutex.unlock(); }

  /// Writes the config out
  AREXPORT bool writeConfig(void);
  /// Notifies the clients that the config was updated
  AREXPORT bool configUpdated(ArServerClient *client = NULL);
  
  /// Changes the variables that prevent changes
  void setPreventChanges(bool preventChanges = false,
			 const char *preventChangesString = NULL);

  /// loads the whole of a default file (for internal use)
  AREXPORT bool loadDefaultsFromFile(void);
  /// Parses a line of the default config (for internal use)
  AREXPORT bool loadDefaultsFromPacket(ArNetPacket *packet);
  /// Creates an empty default config...
  AREXPORT void createEmptyConfigDefaults(void);

  /// Changes if factory is allowed... this is internal, only for when
  /// that decision is deferred
  void setAllowFactory(bool allowFactory) 
    {  myPermissionAllowFactory = allowFactory; }
  /// Changes if factory is allowed... this is internal, only for when
  /// that decision is deferred
  bool getAllowFactory(void)
    { return myPermissionAllowFactory; }
protected:

  AREXPORT void doGetConfigBySections(ArServerClient *client, 
                                      ArNetPacket *packet,
                                      int version);

  /// Helper method for the get config callbacks (e.g. getConfigBySections, getConfig, ...).
  AREXPORT void handleGetConfig(ArServerClient *client, 
                                ArNetPacket *packet,
                                bool isMultiplePackets,
                                ArPriority::Priority lastPriority,
                                bool isSendIneditablePriorities,
                                int version);

  /// Helper method for the get config callbacks (e.g. getConfigBySections, getConfig, ...).
  AREXPORT bool handleGetConfigSection(ArNetPacket &sending,
                                       ArServerClient *client, 
                                      ArNetPacket *packet,
                                      bool isMultiplePackets,
                                      ArPriority::Priority lastPriority,
                                      bool isSendIneditablePriorities,
                                      int version,
                                      ArConfigSection *section,
                                      int startIndex,
                                      int paramCount,
                                      int sectionIndex,
                                      std::set<std::string> &sentParams);


  /// Internal method that handles a setConfig packet for myConfig or
  /// myDefaults
  bool internalSetConfig(ArServerClient *client, 
                         ArNetPacket *packet,
                         int version,
                         bool isMultiplePackets = false);

  /// just creates the default config... (internal, don't use)
  void createDefaultConfig(const char *defaultFileBaseDir);
  /// Adds the default config callbacks;
  void addDefaultServerCommands(void);

  /// Determines the last editable priority based on the input flags
  ArPriority::Priority findLastEditablePriority();

  ArPriority::Priority convertToPriority(int priorityVal,
                                         ArPriority::Priority defaultPriority);


protected:
  
  std::string myRobotName;
  std::string myLogPrefix;

  ArServerBase *myServer;
  ArConfig *myConfig;


  ArConfig *myDefault;
  std::string myDefaultFile;
  std::string myDefaultFileBaseDir;
  ArMutex myDefaultConfigMutex;
  bool myAddedDefaultServerCommands;

  bool myPermissionAllowFactory;
  bool myPreventChanges;
  std::string myPreventChangesString;

  ArMutex myConfigMutex;
  
  std::list<ArFunctor *> myPreWriteCallbacks;
  std::list<ArFunctor *> myPostWriteCallbacks;
  std::list<ArFunctor *> myConfigUpdatedCallbacks;

  ArCallbackList myRestartIOCBList;
  ArFunctor *myRestartSoftwareCB;
  bool myRestartSoftwareCBSet;
  ArFunctor *myRestartHardwareCB;
  bool myRestartHardwareCBSet;

  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetConfigBySectionsCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetConfigBySectionsV2CB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetConfigBySectionsV3CB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetConfigCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> mySetConfigCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> mySetConfigBySectionsCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> mySetConfigBySectionsV2CB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myReloadConfigCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetConfigDefaultsCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetConfigSectionFlagsCB;
  ArFunctor2C<ArServerHandlerConfig, ArServerClient*, ArNetPacket *> myGetLastEditablePriorityCB;

};

#endif