You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

snfXCImgr.hpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // snfXCImgr.hpp
  2. // Copyright (C) 2007 - 2009 ARM Research Labs, LLC.
  3. // See www.armresearch.com for the copyright terms.
  4. // XML Command Interface manager.
  5. // This module uperates a TCP server to accept requests for scans, GBUdb
  6. // operations, etc on behalf of an snf_EngineHandler.
  7. #ifndef included_snfXCImgr_hpp
  8. #define included_snfXCImgr_hpp
  9. #include <string>
  10. #include <queue>
  11. #include "CodeDweller/timing.hpp"
  12. #include "CodeDweller/threading.hpp"
  13. #include "CodeDweller/networking.hpp"
  14. #include "SNFMulti/snf_xci.hpp"
  15. namespace SNFMulti {
  16. // We need to know these exist ;-)
  17. class snf_RulebaseHandler; // These exist.
  18. class snf_EngineHandler; // These exist.
  19. // Handy references and "standards"
  20. static const std::string XCIErrorResponse = // Unrecognized request error.
  21. "<snf><xci><error message=\'What was that?\'/></xci></snf>\n";
  22. static const std::string XCIBadSetResponse = // Empty GBUdb set command error.
  23. "<snf><xci><error message=\'No changes in set. Use test!\'/></xci></snf>\n";
  24. // snfXCIServerCommandHandler Base Class for Server Command Processing.
  25. class snfXCIServerCommandHandler { // Server Command Handler Base Class.
  26. public:
  27. virtual std::string processXCIRequest(snf_xci& X); // Server provides a useful processor.
  28. };
  29. // snfXCIJob encapsulates a single XCI transaction.
  30. class snfXCIJob { // Job Packet.
  31. public:
  32. std::string Request; // XCI formatted request.
  33. std::string Response; // XCI formatted response.
  34. int SetupTime; // Setup time so far in ms.
  35. void clear(); // Clear the buffers.
  36. };
  37. // snfXCIJobProcessor encapsulates the logic to respond to an XCI request.
  38. class snfXCIJobProcessor { // XCI job processor.
  39. private:
  40. snf_xci myXCI; // XCI interpreter.
  41. snf_RulebaseHandler* myHome; // Rulebase to use.
  42. snf_EngineHandler* myEngine; // Scanner (set up internally).
  43. bool isScanJob(); // True if myXCI is a scan job.
  44. bool isGBUdbJob(); // True if myXCI is a GBUdb job.
  45. bool isReportJob(); // True if myXCI is a Report job.
  46. bool isCommandJob(); // True if myXCI is a Command job.
  47. void processScan(snfXCIJob& J); // Process a scan request.
  48. std::string processGBUdb(); // Process a GBUdb request.
  49. std::string processStatusReport(); // Process a report request.
  50. public:
  51. snfXCIJobProcessor(snf_RulebaseHandler* H); // Setup scanner.
  52. ~snfXCIJobProcessor(); // Tear down scanner.
  53. void process(snfXCIJob& J); // Process a Job.
  54. };
  55. // ChannelJob encapsulates a Client Job while in the queue and how long it has
  56. // been in the system (since created).
  57. class ChannelJob { // Wraper for job queue.
  58. private:
  59. CodeDweller::TCPClient* myClient; // We have a TCPClient.
  60. CodeDweller::Timer Lifetime; // We have a timer.
  61. public:
  62. ChannelJob(); // We can be blank but usually
  63. ChannelJob(CodeDweller::TCPClient* C); // we are created like this.
  64. CodeDweller::msclock Age(); // How old is this job?
  65. CodeDweller::TCPClient* Client(); // What client does it hold?
  66. };
  67. // snfXCITCPChannel encapsulates the logic to queue and handle TCPClients for
  68. // the XCI interface. The queued TCPClients each represent a single request.
  69. // Each request is handled in turn by reading the request into an snfXCIJob,
  70. // handing that snfXCIJob to an snfXCIJobProcessor, transmitting the result
  71. // back to the TCPClient, closing the connection, and recycling the snfXCIJob
  72. // object for the next round.
  73. // snfXCITCPChannel shuts down when given a NULL TCPClient; This allows any
  74. // jobs in queue to be handled before the thread stops. To shut down a channel
  75. // { C->submit(NULL); C->join(); delete C; C = NULL;}
  76. const int LineBufferSize = 256; // Line buffer size.
  77. class snfXCITCPChannel : private CodeDweller::Thread { // TCPClient processor & queue.
  78. private:
  79. snf_RulebaseHandler* myHome; // Rulebase handler.
  80. snfXCIJobProcessor Processor; // XCI processor.
  81. snfXCIJob Job; // XCI Job buffer.
  82. volatile int LatestSize; // Queue Size Blinking Light.
  83. CodeDweller::Mutex QueueMutex; // Serializes queue changes.
  84. CodeDweller::ProductionGateway QueueGateway; // Keeps track of give and take.
  85. std::queue<ChannelJob> JobQueue; // Queue of clients.
  86. void give(ChannelJob& J); // give a client to the queue.
  87. ChannelJob take(); // take a client from the queue.
  88. char LineBuffer[LineBufferSize]; // Read Line Buffer.
  89. void readRequest(CodeDweller::TCPClient* Client); // Read Job.Request from Client.
  90. void writeResponse(CodeDweller::TCPClient* Client); // Write Job.Request from Client.
  91. void myTask(); // Thread's main loop.
  92. public:
  93. snfXCITCPChannel(snf_RulebaseHandler* H, std::string N); // Create these with a home rulebase.
  94. ~snfXCITCPChannel(); // Destroy them very carefully.
  95. int Size(); // Keep track of how full they are.
  96. void submit(CodeDweller::TCPClient* C); // This is how we submit jobs.
  97. const static CodeDweller::ThreadType Type; // The thread's type.
  98. const static CodeDweller::ThreadState XCI_Wait;
  99. const static CodeDweller::ThreadState XCI_Read;
  100. const static CodeDweller::ThreadState XCI_Process;
  101. const static CodeDweller::ThreadState XCI_Write;
  102. const static CodeDweller::ThreadState XCI_Close;
  103. const static CodeDweller::ThreadState XCI_Clear;
  104. const static CodeDweller::ThreadState XCI_Shutdown;
  105. //const static ThreadState ThreadInitialized; // Constructed successfully.
  106. };
  107. // snfXCImgr encapsulates a service engine that takes XCI requests via TCP,
  108. // performs the required actions, and returns an XCI response. It also checks
  109. // to see if the configuration for the XCI interface has changed.
  110. class snfXCImgr : private CodeDweller::Thread { // XCI manager.
  111. private:
  112. CodeDweller::Mutex ChannelMutex; // Safety Channel Up/Down events.
  113. bool CFG_XCI_ON; // Is XCI turned on?
  114. int CFG_XCI_PORT; // What port we listen to?
  115. void checkCFG(); // Checks the configuration.
  116. snf_RulebaseHandler* myHome; // Rulebase handler to service.
  117. snfXCITCPChannel* C0; // XCI channel 0
  118. snfXCITCPChannel* C1; // XCI channel 1
  119. snfXCITCPChannel* C2; // XCI channel 2
  120. snfXCITCPChannel* C3; // XCI channel 3
  121. snfXCITCPChannel* C4; // XCI channel 4
  122. snfXCITCPChannel* C5; // XCI channel 5
  123. snfXCITCPChannel* C6; // XCI channel 6
  124. snfXCITCPChannel* C7; // XCI channel 7
  125. snfXCITCPChannel* BestAvailableChannel(); // Selects XCI channel w/ lowest queue.
  126. CodeDweller::TCPListener* Listener; // XCI Listener.
  127. bool XCI_UP; // True if XCI is alive.
  128. void startup_Listener(); // Listener startup function.
  129. void shutdown_Listener(); // Listener shutdown function.
  130. void startup_XCI(); // XCI startup function.
  131. void shutdown_XCI(); // XCI shutdown function.
  132. void myTask(); // Main thread task.
  133. volatile int diagLoopCount;
  134. volatile int diagClientCount;
  135. bool TimeToStop; // True when shutting down.
  136. public:
  137. snfXCImgr(); // Construct with no home.
  138. ~snfXCImgr(); // Destroy to shut down.
  139. void linkHome(snf_RulebaseHandler* Home); // Link to Home and set up shop.
  140. int TotalQueue(); // Return the total work queue size.
  141. void stop(); // Called to shut down.
  142. int pollLoopCount(); // Get diagnostic loop count.
  143. int pollClientCount(); // Get diagnostic client count.
  144. const static CodeDweller::ThreadType Type; // The thread's type.
  145. const static CodeDweller::ThreadState XCI_InitialConfig; // Getting initial configuration.
  146. const static CodeDweller::ThreadState XCI_InitialStartup; // Performing first startup.
  147. const static CodeDweller::ThreadState XCI_CheckConfig; // Checking configuration.
  148. const static CodeDweller::ThreadState XCI_PollingListener; // Polling Listener for jobs.
  149. const static CodeDweller::ThreadState XCI_SubmittingJob; // Submitting a new job.
  150. const static CodeDweller::ThreadState XCI_ListenerDown; // Listener is down.
  151. const static CodeDweller::ThreadState XCI_Stopping; // XCImgr Exiting Big Loop
  152. };
  153. } // namespace SNFMulti
  154. #endif