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

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