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.

161 lines
3.2KB

  1. #include "TSOSCCommunicator.hpp"
  2. #include <thread> // std::thread
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <map>
  6. #include <mutex>
  7. //#include "util.hpp"
  8. #define MIN_PORT 1000
  9. #define MAX_PORT 0xFFFF
  10. // The connector
  11. TSOSCConnector* TSOSCConnector::_instance = NULL;
  12. TSOSCConnector::TSOSCConnector()
  13. {
  14. _lastId = 0;
  15. return;
  16. }
  17. TSOSCConnector* TSOSCConnector::Connector()
  18. {
  19. if (!_instance)
  20. _instance = new TSOSCConnector();
  21. return _instance;
  22. }
  23. // Get an id for the module instance.
  24. int TSOSCConnector::getId()
  25. {
  26. std::lock_guard<std::mutex> lock(_mutex);
  27. return ++_lastId;
  28. }
  29. // Register the usage of these ports.
  30. bool TSOSCConnector::registerPorts(int id, uint16_t txPort, uint16_t rxPort)
  31. {
  32. std::lock_guard<std::mutex> lock(_mutex);
  33. int tx = -1;
  34. int rx = -1;
  35. if (_portMap.count(txPort) < 1 || _portMap[txPort] == id)
  36. {
  37. tx = txPort;
  38. }
  39. if (_portMap.count(rxPort) < 1 || _portMap[rxPort] == id)
  40. {
  41. rx = rxPort;
  42. }
  43. if (tx > -1 && rx > -1)
  44. {
  45. _portMap[txPort] = id;
  46. _portMap[rxPort] = id;
  47. return true;
  48. }
  49. else
  50. {
  51. return false; // Do nothing
  52. }
  53. }
  54. // Register the usage of these ports.
  55. bool TSOSCConnector::registerPort(int id, uint16_t port)
  56. {
  57. std::lock_guard<std::mutex> lock(_mutex);
  58. int tx = -1;
  59. if (_portMap.count(port) < 1 || _portMap[port] == id)
  60. {
  61. tx = port;
  62. }
  63. if (tx > -1)
  64. {
  65. _portMap[port] = id;
  66. return true;
  67. }
  68. else
  69. {
  70. return false; // Do nothing
  71. }
  72. }
  73. // Clear the usage of these ports.
  74. bool TSOSCConnector::clearPorts(int id, uint16_t txPort, uint16_t rxPort)
  75. {
  76. std::lock_guard<std::mutex> lock(_mutex);
  77. std::map<uint16_t, int>::iterator it;
  78. int nErased = 0;
  79. it = _portMap.find(txPort);
  80. if (it != _portMap.end() && _portMap[txPort] == id)
  81. {
  82. _portMap.erase(it);
  83. nErased++;
  84. }
  85. it = _portMap.find(rxPort);
  86. if (it != _portMap.end() && _portMap[rxPort] == id)
  87. {
  88. _portMap.erase(it);
  89. nErased++;
  90. }
  91. return nErased == 2;
  92. }
  93. // Clear the usage of these ports.
  94. bool TSOSCConnector::clearPort(int id, uint16_t port)
  95. {
  96. std::lock_guard<std::mutex> lock(_mutex);
  97. std::map<uint16_t, int>::iterator it;
  98. it = _portMap.find(port);
  99. if (it != _portMap.end() && _portMap[port] == id)
  100. {
  101. _portMap.erase(it);
  102. return true;
  103. }
  104. return false;
  105. }
  106. // See if the port is in use (returns the id of the module using it or 0 if it is free).
  107. int TSOSCConnector::portInUse(uint16_t port)
  108. {
  109. std::lock_guard<std::mutex> lock(_mutex);
  110. std::map<uint16_t, int>::iterator it;
  111. int id = 0;
  112. it = _portMap.find(port);
  113. if (it != _portMap.end())
  114. {
  115. id = _portMap[port];
  116. }
  117. return id;
  118. }
  119. // Get an available port.
  120. uint16_t TSOSCConnector::getAvailablePort(int id, uint16_t desiredPort)
  121. {
  122. std::lock_guard<std::mutex> lock(_mutex);
  123. bool portFound = false;
  124. uint16_t port = desiredPort;
  125. uint16_t portA, portB;
  126. if (_portMap.count(port) < 1 || _portMap[port] == id)
  127. {
  128. portFound = true;
  129. }
  130. else
  131. {
  132. portA = port;
  133. portB = port;
  134. while (!portFound && (portA < MAX_PORT || portB > MIN_PORT))
  135. {
  136. if (portA < MAX_PORT)
  137. {
  138. portA += 2;
  139. portFound = _portMap.count(portA) < 1 || _portMap[portA] == id;
  140. if (portFound)
  141. port = portA;
  142. }
  143. if (!portFound && portB > MIN_PORT)
  144. {
  145. portB -= 2;
  146. portFound = _portMap.count(portB) < 1 || _portMap[portB] == id;
  147. if (portFound)
  148. port = portB;
  149. }
  150. } // end while
  151. }
  152. return (portFound) ? port : 0;
  153. }