#include #include #include #include "utils.h" #include "manager.h" // declare of scoped vars and funcs namespace hm { std::mutex gDeviceMtx; std::vector> gDevicesVec; bool gSdkOk = false; std::vector gSearchHandlers; void disconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo); void reconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo); [[noreturn]] void ManagerLoop(); void startSearch(); void stopSearch(); void onDeviceFound(LLONG handler, DEVICE_NET_INFO_EX2 *deviceInfo, void *userData); bool deviceInclude(const std::string &seq); bool checkDevice(const Device *device, const bool &isFace, std::string &msg); Device *getDeviceBySeq(const std::string &seq); Device *getDeviceByLoginId(const LLONG &loginId); } // implement of scoped funcs namespace hm { void disconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo) { Log(Info, "loginId: 0x%lx, device[ip: %s, port: %d], user: %ld", loginId, dIp, dPort, userInfo); Device *device = getDeviceByLoginId(loginId); if (device != nullptr) device->online = false; } void reconnectFunc(LLONG loginId, char *dIp, LONG dPort, LDWORD userInfo) { Log(Info, "loginId: 0x%lx, device[ip: %s, port: %d], user: %ld", loginId, dIp, dPort, userInfo); Device *device = getDeviceByLoginId(loginId); if (device != nullptr) device->online = true; } [[noreturn]] void ManagerLoop() { bool first = true; while (true) { startSearch(); stopSearch(); for (const auto &itr: gDevicesVec) { itr->Start(); if (itr->online) { itr->isFaceDevice ? itr->queryFaceUsers() : (itr->queryCarWoBList(true), itr->queryCarWoBList(false)); } } if (first) { first = false; Log(Info, "All device managed"); } sleep(gConfSearchGap); } } void startSearch() { NET_IN_STARTSERACH_DEVICE pInBuf = {0}; NET_OUT_STARTSERACH_DEVICE pOutBuf = {0}; pInBuf.dwSize = sizeof(NET_IN_STARTSERACH_DEVICE); pInBuf.cbSearchDevices = onDeviceFound; pInBuf.pUserData = nullptr; pOutBuf.dwSize = sizeof(NET_OUT_STARTSERACH_DEVICE); std::vector localIPs = getIpList(); for (const std::string &ip : localIPs) { memset(pInBuf.szLocalIp, 0, MAX_LOCAL_IP_LEN); strncpy(pInBuf.szLocalIp, ip.c_str(), MAX_LOCAL_IP_LEN - 1); LLONG handler = CLIENT_StartSearchDevicesEx(&pInBuf, &pOutBuf); gSearchHandlers.push_back(handler); } Log(Trace, "search local area network device for %ds ...", gConfSearchDuration); sleep(gConfSearchDuration); } void stopSearch() { for (const LLONG handler: gSearchHandlers) CLIENT_StopSearchDevices(handler); gSearchHandlers.clear(); Log(Trace, "search stopped ~"); } void onDeviceFound(LLONG handler, DEVICE_NET_INFO_EX2 *deviceInfo, void *userData) { std::lock_guard lock(gDeviceMtx); // TODO: device-include -> update, !device-include -> push_back if (deviceInfo->stuDevInfo.iIPVersion == 4 && !deviceInclude(deviceInfo->stuDevInfo.szSerialNo)) { gDevicesVec.push_back(std::make_unique(deviceInfo)); Log( Info, "new device found, {ip: %s, mac: %s, seq: %s, type: %s}", deviceInfo->stuDevInfo.szIP, deviceInfo->stuDevInfo.szMac, deviceInfo->stuDevInfo.szSerialNo, deviceInfo->stuDevInfo.szDetailType ); } } bool deviceInclude(const std::string &seq) { for (const auto &itr : gDevicesVec) if (itr->seq == seq) return true; return false; } bool checkDevice(const Device *device, const bool &isFace, std::string &msg) { if (device == nullptr) { msg = "device seq error"; return false; } if (!device->online) { msg = "device offline"; return false; } if (device->isFaceDevice != isFace) { msg = "device type error"; return false; } return true; } Device *getDeviceBySeq(const std::string &seq) { std::lock_guard lock(gDeviceMtx); for (const auto &itr : gDevicesVec) if (itr->seq == seq) return itr.get(); return nullptr; } Device *getDeviceByLoginId(const LLONG &loginId) { std::lock_guard lock(gDeviceMtx); for (const auto &itr : gDevicesVec) if (itr->loginId == loginId) return itr.get(); return nullptr; } } namespace hm { void StartManager() { gSdkOk = CLIENT_Init(disconnectFunc, 0); CLIENT_SetAutoReconnect(reconnectFunc, 0); CLIENT_SetConnectTime(1000, 3); if (!gSdkOk) { LogM(Error, "SDK init failed."); throw std::logic_error("SDK init failed."); } Log(Trace, "SDK init success"); std::thread thread(ManagerLoop); thread.detach(); } bool managerGetFaceDevices(std::vector &devices, std::string &msg) { for (const auto &itr : gDevicesVec) { if (itr->isFaceDevice) devices.push_back(itr->getJsonStr()); } return true; } bool managerGetFaceDeviceUsers(const std::string &seq, std::vector &users, std::string &msg) { Device *device = getDeviceBySeq(seq); if (!checkDevice(device, true, msg)) return false; return device->getFaceUsers(users, msg); } bool managerInsertFaceDeviceUser(const std::string &seq, const User &user, std::string &msg) { Device *device = getDeviceBySeq(seq); if (!checkDevice(device, true, msg)) return false; return device->insertFaceUser(user, msg); } bool managerRemoveFaceDeviceUser(const std::string &seq, const std::string &uid, std::string &msg) { Device *device = getDeviceBySeq(seq); if (!checkDevice(device, true, msg)) return false; return device->removeFaceUser(uid, msg); } bool managerGetCarDevices(std::vector &devices, std::string &msg) { for (const auto &itr : gDevicesVec) { if (!itr->isFaceDevice) devices.push_back(itr->getJsonStr()); } return true; } bool managerGetCarDeviceWoBList( const std::string &seq, const bool &isBlack, std::vector &list, std::string &msg ) { Device *device = getDeviceBySeq(seq); if (!checkDevice(device, false, msg)) return false; return device->getCarWoBList(isBlack, list, msg); } bool managerInsertCarDeviceWoBList( const std::string &seq, const bool &isBlack, std::vector &list, std::string &msg ) { Device *device = getDeviceBySeq(seq); if (!checkDevice(device, false, msg)) return false; return device->insertCarWoBList(isBlack, list, msg); } bool managerRemoveCarDeviceWoBList( const std::string &seq, const bool &isBlack, std::vector &cids, std::string &msg ) { Device *device = getDeviceBySeq(seq); if (!checkDevice(device, false, msg)) return false; return device->removeCarWoBList(isBlack, cids, msg); } void StopManager() { stopSearch(); gDevicesVec.clear(); if (gSdkOk) { CLIENT_Cleanup(); gSdkOk = false; } Log(Info, "manager stopped ~"); } }