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.

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