manager.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include <unistd.h>
  2. #include <cstring>
  3. #include <thread>
  4. #include "utils.h"
  5. #include "manager.h"
  6. // declare of scoped vars and funcs
  7. namespace hm {
  8. std::mutex gDeviceMtx;
  9. std::vector<std::unique_ptr<Device>> gDevicesVec;
  10. bool gSdkOk = false;
  11. std::vector<LLONG> gSearchHandlers;
  12. void disconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo);
  13. void reconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo);
  14. [[noreturn]] void ManagerLoop();
  15. void startSearch();
  16. void stopSearch();
  17. void onDeviceFound(LLONG handler, DEVICE_NET_INFO_EX2 *deviceInfo, void *userData);
  18. bool deviceInclude(const std::string &seq);
  19. bool checkDevice(const Device *device, const bool &isFace, std::string &msg);
  20. Device *getDeviceBySeq(const std::string &seq);
  21. Device *getDeviceByLoginId(const LLONG &loginId);
  22. }
  23. // implement of scoped funcs
  24. namespace hm {
  25. void disconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo) {
  26. Log(Info, "loginId: 0x%lx, device[ip: %s, port: %d], user: %ld", loginId, dIp, dPort, userInfo);
  27. Device *device = getDeviceByLoginId(loginId);
  28. if (device != nullptr) device->online = false;
  29. }
  30. void reconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo) {
  31. Log(Info, "loginId: 0x%lx, device[ip: %s, port: %d], user: %ld", loginId, dIp, dPort, userInfo);
  32. Device *device = getDeviceByLoginId(loginId);
  33. if (device != nullptr) device->online = true;
  34. }
  35. [[noreturn]] void ManagerLoop() {
  36. bool first = true;
  37. while (true) {
  38. startSearch();
  39. stopSearch();
  40. for (const auto &itr: gDevicesVec) {
  41. itr->Start();
  42. if (itr->online) {
  43. itr->isFaceDevice ?
  44. itr->queryFaceUsers() :
  45. (itr->queryCarWoBList(true), itr->queryCarWoBList(false));
  46. }
  47. }
  48. if (first) {
  49. first = false;
  50. Log(Info, "All device managed");
  51. }
  52. sleep(gConfSearchGap);
  53. }
  54. }
  55. void startSearch() {
  56. NET_IN_STARTSERACH_DEVICE pInBuf = {0};
  57. NET_OUT_STARTSERACH_DEVICE pOutBuf = {0};
  58. pInBuf.dwSize = sizeof(NET_IN_STARTSERACH_DEVICE);
  59. pInBuf.cbSearchDevices = onDeviceFound;
  60. pInBuf.pUserData = nullptr;
  61. pOutBuf.dwSize = sizeof(NET_OUT_STARTSERACH_DEVICE);
  62. std::vector<std::string> localIPs = getIpList();
  63. for (const std::string &ip : localIPs) {
  64. memset(pInBuf.szLocalIp, 0, MAX_LOCAL_IP_LEN);
  65. strncpy(pInBuf.szLocalIp, ip.c_str(), MAX_LOCAL_IP_LEN - 1);
  66. LLONG handler = CLIENT_StartSearchDevicesEx(&pInBuf, &pOutBuf);
  67. gSearchHandlers.push_back(handler);
  68. }
  69. Log(Trace, "search local area network device for %ds ...", gConfSearchDuration);
  70. sleep(gConfSearchDuration);
  71. }
  72. void stopSearch() {
  73. for (const LLONG handler: gSearchHandlers) CLIENT_StopSearchDevices(handler);
  74. gSearchHandlers.clear();
  75. Log(Trace, "search stopped ~");
  76. }
  77. void onDeviceFound(LLONG handler, DEVICE_NET_INFO_EX2 *deviceInfo, void *userData) {
  78. std::lock_guard<std::mutex> lock(gDeviceMtx);
  79. // TODO: device-include -> update, !device-include -> push_back
  80. if (deviceInfo->stuDevInfo.iIPVersion == 4 && !deviceInclude(deviceInfo->stuDevInfo.szSerialNo)) {
  81. gDevicesVec.push_back(std::make_unique<Device>(deviceInfo));
  82. Log(
  83. Info, "new device found, {ip: %s, mac: %s, seq: %s, type: %s}",
  84. deviceInfo->stuDevInfo.szIP, deviceInfo->stuDevInfo.szMac, deviceInfo->stuDevInfo.szSerialNo,
  85. deviceInfo->stuDevInfo.szDetailType
  86. );
  87. }
  88. }
  89. bool deviceInclude(const std::string &seq) {
  90. for (const auto &itr : gDevicesVec) if (itr->seq == seq) return true;
  91. return false;
  92. }
  93. bool checkDevice(const Device *device, const bool &isFace, std::string &msg) {
  94. if (device == nullptr) {
  95. msg = "device seq error";
  96. return false;
  97. }
  98. if (!device->online) {
  99. msg = "device offline";
  100. return false;
  101. }
  102. if (device->isFaceDevice != isFace) {
  103. msg = "device type error";
  104. return false;
  105. }
  106. return true;
  107. }
  108. Device *getDeviceBySeq(const std::string &seq) {
  109. std::lock_guard<std::mutex> lock(gDeviceMtx);
  110. for (const auto &itr : gDevicesVec) if (itr->seq == seq) return itr.get();
  111. return nullptr;
  112. }
  113. Device *getDeviceByLoginId(const LLONG &loginId) {
  114. std::lock_guard<std::mutex> lock(gDeviceMtx);
  115. for (const auto &itr : gDevicesVec) if (itr->loginId == loginId) return itr.get();
  116. return nullptr;
  117. }
  118. }
  119. namespace hm {
  120. void StartManager() {
  121. gSdkOk = CLIENT_Init(disconnectFunc, 0);
  122. CLIENT_SetAutoReconnect(reconnectFunc, 0);
  123. CLIENT_SetConnectTime(1000, 3);
  124. if (!gSdkOk) {
  125. LogM(Error, "SDK init failed.");
  126. throw std::logic_error("SDK init failed.");
  127. }
  128. Log(Trace, "SDK init success");
  129. std::thread thread(ManagerLoop);
  130. thread.detach();
  131. }
  132. bool managerGetFaceDevices(std::vector<std::string> &devices, std::string &msg) {
  133. for (const auto &itr : gDevicesVec) {
  134. if (itr->isFaceDevice) devices.push_back(itr->getJsonStr());
  135. }
  136. return true;
  137. }
  138. bool managerGetFaceDeviceUsers(const std::string &seq, std::vector<std::string> &users, std::string &msg) {
  139. Device *device = getDeviceBySeq(seq);
  140. if (!checkDevice(device, true, msg)) return false;
  141. return device->getFaceUsers(users, msg);
  142. }
  143. bool managerInsertFaceDeviceUser(const std::string &seq, const User &user, std::string &msg) {
  144. Device *device = getDeviceBySeq(seq);
  145. if (!checkDevice(device, true, msg)) return false;
  146. return device->insertFaceUser(user, msg);
  147. }
  148. bool managerRemoveFaceDeviceUser(const std::string &seq, const std::string &uid, std::string &msg) {
  149. Device *device = getDeviceBySeq(seq);
  150. if (!checkDevice(device, true, msg)) return false;
  151. return device->removeFaceUser(uid, msg);
  152. }
  153. bool managerGetCarDevices(std::vector<std::string> &devices, std::string &msg) {
  154. for (const auto &itr : gDevicesVec) {
  155. if (!itr->isFaceDevice) devices.push_back(itr->getJsonStr());
  156. }
  157. return true;
  158. }
  159. bool managerGetCarDeviceWoBList(
  160. const std::string &seq, const bool &isBlack, std::vector<std::string> &list, std::string &msg
  161. ) {
  162. Device *device = getDeviceBySeq(seq);
  163. if (!checkDevice(device, false, msg)) return false;
  164. return device->getCarWoBList(isBlack, list, msg);
  165. }
  166. bool managerInsertCarDeviceWoBList(
  167. const std::string &seq, const bool &isBlack, std::vector<Plate> &list, std::string &msg
  168. ) {
  169. Device *device = getDeviceBySeq(seq);
  170. if (!checkDevice(device, false, msg)) return false;
  171. return device->insertCarWoBList(isBlack, list, msg);
  172. }
  173. bool managerRemoveCarDeviceWoBList(
  174. const std::string &seq, const bool &isBlack, std::vector<int> &cids, std::string &msg
  175. ) {
  176. Device *device = getDeviceBySeq(seq);
  177. if (!checkDevice(device, false, msg)) return false;
  178. return device->removeCarWoBList(isBlack, cids, msg);
  179. }
  180. void StopManager() {
  181. stopSearch();
  182. gDevicesVec.clear();
  183. if (gSdkOk) {
  184. CLIENT_Cleanup();
  185. gSdkOk = false;
  186. }
  187. Log(Info, "manager stopped ~");
  188. }
  189. }