reader_service.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. #include "reader_service.h"
  2. #include "../utils.h"
  3. #include <iostream>
  4. #include <thread>
  5. #include <chrono>
  6. #include <mutex>
  7. #include <sstream>
  8. void PrintLogMessage(const std::string &message)
  9. {
  10. CreateAndAttachConsole();
  11. std::cout << message << std::endl;
  12. }
  13. ReaderService *ReaderService::GetInstance()
  14. {
  15. static ReaderService instance;
  16. return &instance;
  17. }
  18. std::vector<std::string> ReaderService::ScanUsb()
  19. {
  20. PrintLogMessage("Scanning USB...");
  21. std::vector<std::string> usb_devices;
  22. int iHidNum = SWHid_GetUsbCount();
  23. for (int i = 0; i < iHidNum; i++)
  24. {
  25. char arrHidName[256];
  26. SWHid_GetUsbInfo(static_cast<unsigned short>(i), arrHidName);
  27. usb_devices.push_back(arrHidName);
  28. }
  29. return usb_devices;
  30. }
  31. bool ReaderService::Connect(int deviceIndex)
  32. {
  33. unsigned char arrBuffer[256] = {0};
  34. // Close previous connection (if exists)
  35. if (connected_)
  36. {
  37. SWHid_SetCallback(NULL);
  38. SWHid_CloseDevice();
  39. }
  40. if (SWHid_OpenDevice(static_cast<unsigned short>(deviceIndex)) == FALSE)
  41. {
  42. PrintLogMessage("Failed to connect to device!");
  43. return false;
  44. }
  45. // Get device information
  46. if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false) // failed
  47. {
  48. Sleep(10);
  49. if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false) // failed
  50. {
  51. SWHid_CloseDevice();
  52. PrintLogMessage("Failed to get device info!");
  53. return false;
  54. }
  55. }
  56. connected_ = true;
  57. // Set callback function
  58. // SWHid_SetCallback(ReaderService::DeviceCallback);
  59. // Extract device info
  60. int softVer = static_cast<int>(arrBuffer[0]);
  61. int hardVer = static_cast<int>(arrBuffer[1]);
  62. std::string softVersion = std::to_string(softVer >> 4) + "." + std::to_string(softVer & 0x0F);
  63. std::string hardVersion = std::to_string(hardVer >> 4) + "." + std::to_string(hardVer & 0x0F);
  64. // Extract device SN from buffer[2] to buffer[9] (8 bytes)
  65. std::string deviceSN = "";
  66. for (int i = 2; i < 10; i++)
  67. {
  68. char hex[3];
  69. sprintf_s(hex, sizeof(hex), "%.2X", arrBuffer[i]);
  70. deviceSN += hex;
  71. }
  72. std::string log_message = "Connected to device successfully! SN: " + deviceSN +
  73. ", SoftVer: " + softVersion +
  74. ", HardVer: " + hardVersion;
  75. PrintLogMessage(log_message);
  76. return true;
  77. }
  78. void ReaderService::Disconnect()
  79. {
  80. if (connected_)
  81. {
  82. StopRead(); // Stop reading
  83. SWHid_SetCallback(NULL);
  84. SWHid_CloseDevice();
  85. connected_ = false;
  86. PrintLogMessage("Disconnected from device.");
  87. }
  88. }
  89. bool ReaderService::StartRead()
  90. {
  91. if (!connected_)
  92. {
  93. PrintLogMessage("Not connected to any device!");
  94. return false;
  95. }
  96. // SWHid_SetDeviceOneParam(0xFF, 0x02, 0x01); // Set Workmode as Activemode
  97. // Set working mode to answer mode
  98. if (SWHid_SetDeviceOneParam(0xFF, 0x02, 0x00) == false) // Set Workmode as Answermode
  99. {
  100. PrintLogMessage("Failed to set device to answer mode!");
  101. return false;
  102. }
  103. reading_ = true;
  104. timer_running_ = true;
  105. tags_.clear();
  106. // Start timer thread to periodically call AnswerMode
  107. timer_thread_ = std::make_unique<std::thread>(&ReaderService::RunTimer, this);
  108. // Start a thread to periodically send tag list to UI
  109. callback_thread_ = std::make_unique<std::thread>([this]()
  110. {
  111. while (timer_running_) {
  112. SendTagList();
  113. std::this_thread::sleep_for(std::chrono::seconds(1));
  114. } });
  115. // // Start a separate thread to automatically stop reading after 3 seconds
  116. // auto stop_thread = std::make_unique<std::thread>([this]() {
  117. // std::this_thread::sleep_for(std::chrono::seconds(3));
  118. // if (reading_) {
  119. // StopRead();
  120. // PrintLogMessage("Automatically stopped reading after 3 seconds.");
  121. // }
  122. // });
  123. // // Detach the thread to run independently and clean up resources
  124. // stop_thread->detach();
  125. PrintLogMessage("Started reading in answer mode. Will auto-stop after 3 seconds.");
  126. return true;
  127. }
  128. void ReaderService::StopRead()
  129. {
  130. if (reading_)
  131. {
  132. // Stop the timer thread
  133. if (timer_running_)
  134. {
  135. timer_running_ = false;
  136. if (timer_thread_ && timer_thread_->joinable())
  137. {
  138. timer_thread_->join();
  139. }
  140. if (callback_thread_ && callback_thread_->joinable())
  141. {
  142. callback_thread_->join();
  143. }
  144. }
  145. reading_ = false;
  146. PrintLogMessage("Stopped reading.");
  147. }
  148. }
  149. void ReaderService::RunTimer()
  150. {
  151. while (timer_running_)
  152. {
  153. AnswerMode();
  154. std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep for 100ms, similar to the demo
  155. }
  156. }
  157. std::string ReaderService::GetDeviceInfo()
  158. {
  159. if (!connected_)
  160. {
  161. return "";
  162. }
  163. unsigned char arrBuffer[256] = {0};
  164. if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false)
  165. {
  166. Sleep(10);
  167. if (SWHid_GetDeviceSystemInfo(0xFF, arrBuffer) == false)
  168. {
  169. return "";
  170. }
  171. }
  172. // Extract device info
  173. int softVer = static_cast<int>(arrBuffer[0]);
  174. int hardVer = static_cast<int>(arrBuffer[1]);
  175. std::string softVersion = std::to_string(softVer >> 4) + "." + std::to_string(softVer & 0x0F);
  176. std::string hardVersion = std::to_string(hardVer >> 4) + "." + std::to_string(hardVer & 0x0F);
  177. // Extract device SN from buffer[2] to buffer[9] (8 bytes)
  178. std::string deviceSN = "";
  179. for (int i = 2; i < 10; i++)
  180. {
  181. char hex[3];
  182. sprintf_s(hex, sizeof(hex), "%.2X", arrBuffer[i]);
  183. deviceSN += hex;
  184. }
  185. // Create a formatted string with all device info
  186. std::string deviceInfo = "SN:" + deviceSN +
  187. ",SoftVer:" + softVersion +
  188. ",HardVer:" + hardVersion;
  189. std::string log_message = "Device Info - " + deviceInfo;
  190. PrintLogMessage(log_message);
  191. return deviceInfo;
  192. }
  193. // 新增功率查询功能
  194. bool ReaderService::GetPower(unsigned char &power)
  195. {
  196. if (!connected_)
  197. {
  198. PrintLogMessage("Not connected to any device!");
  199. return false;
  200. }
  201. unsigned char bValue = 0;
  202. unsigned char bParamAddr = 0x05; // RFPower parameter address
  203. if (SWHid_ReadDeviceOneParam(0xFF, bParamAddr, &bValue) == false)
  204. {
  205. PrintLogMessage("Failed to read power!");
  206. return false;
  207. }
  208. power = bValue;
  209. std::string log_message = "Power read successfully: " + std::to_string(power);
  210. PrintLogMessage(log_message);
  211. return true;
  212. }
  213. // 新增功率设置功能
  214. bool ReaderService::SetPower(unsigned char power)
  215. {
  216. if (!connected_)
  217. {
  218. PrintLogMessage("Not connected to any device!");
  219. return false;
  220. }
  221. // Check if power is within valid range (based on demo: 5-30)
  222. if (power < 5 || power > 30)
  223. {
  224. std::string log_message = "Invalid power value: " + std::to_string(power) + " (must be between 5-30)";
  225. PrintLogMessage(log_message);
  226. return false;
  227. }
  228. unsigned char bParamAddr = 0x05; // RFPower parameter address
  229. if (SWHid_SetDeviceOneParam(0xFF, bParamAddr, power) == false)
  230. {
  231. PrintLogMessage("Failed to set power!");
  232. return false;
  233. }
  234. std::string log_message = "Power set successfully to: " + std::to_string(power);
  235. PrintLogMessage(log_message);
  236. return true;
  237. }
  238. void ReaderService::DeviceCallback(int msg, int param1, unsigned char *param2, int param3, unsigned char *param4)
  239. {
  240. ReaderService *instance = ReaderService::GetInstance();
  241. if (msg == 2) // Data
  242. {
  243. PrintLogMessage("Data received.");
  244. unsigned short iTagLength = 0;
  245. unsigned short iTagNumber = 0;
  246. iTagLength = static_cast<unsigned short>(param3);
  247. iTagNumber = static_cast<unsigned short>(param1);
  248. unsigned char *pBuffer = NULL;
  249. pBuffer = (unsigned char *)param2;
  250. if (iTagNumber == 0)
  251. return;
  252. int iIndex = 0;
  253. int iLength = 0;
  254. unsigned char *pID;
  255. unsigned char bPackLength = 0;
  256. int iIDLen = 0;
  257. for (iIndex = 0; iIndex < iTagNumber; iIndex++)
  258. {
  259. bPackLength = pBuffer[iLength];
  260. pID = (unsigned char *)&pBuffer[1 + iLength];
  261. std::string str2 = "";
  262. char buffer[256];
  263. sprintf_s(buffer, sizeof(buffer), "Type:%.2X ", pID[0]);
  264. str2 += buffer;
  265. if ((pID[0] & 0x80) == 0x80) // with TimeStamp
  266. {
  267. iIDLen = bPackLength - 7;
  268. }
  269. else
  270. iIDLen = bPackLength - 1;
  271. sprintf_s(buffer, sizeof(buffer), "Ant:%.2X Tag:", pID[1]);
  272. str2 += buffer;
  273. for (int i = 2; i < iIDLen; i++)
  274. {
  275. sprintf_s(buffer, sizeof(buffer), "%.2X ", pID[i]);
  276. str2 += buffer;
  277. }
  278. sprintf_s(buffer, sizeof(buffer), "RSSI:%.2X", pID[iIDLen]);
  279. str2 += buffer;
  280. // Notify UI of new data
  281. if (instance->data_callback_)
  282. {
  283. instance->data_callback_(str2);
  284. }
  285. iLength = iLength + bPackLength + 1;
  286. }
  287. }
  288. else if (msg == 1) // Device Out
  289. {
  290. PrintLogMessage("Device removed.");
  291. if (instance->data_callback_)
  292. {
  293. instance->data_callback_("Device Out");
  294. }
  295. }
  296. else if (msg == 0) // Device Insert
  297. {
  298. PrintLogMessage("Device inserted.");
  299. if (instance->data_callback_)
  300. {
  301. instance->data_callback_("Device Insert");
  302. }
  303. }
  304. }
  305. void ReaderService::AnswerMode()
  306. {
  307. unsigned char arrBuffer[2048] = {0};
  308. unsigned short iTagLength = 0;
  309. unsigned short iTagNumber = 0;
  310. if (SWHid_InventoryG2(0xFF, arrBuffer, &iTagLength, &iTagNumber) == false)
  311. {
  312. PrintLogMessage("Failed to inventory!");
  313. return;
  314. }
  315. if (iTagNumber == 0)
  316. {
  317. // PrintLogMessage("No data!");
  318. return;
  319. }
  320. ReaderService *instance = ReaderService::GetInstance();
  321. int iIndex = 0;
  322. int iLength = 0;
  323. unsigned char *pID;
  324. unsigned char bPackLength = 0;
  325. int iIDLen = 0;
  326. for (iIndex = 0; iIndex < iTagNumber; iIndex++)
  327. {
  328. bPackLength = arrBuffer[iLength];
  329. pID = (unsigned char *)&arrBuffer[1 + iLength];
  330. std::string str2 = "", tag = "";
  331. char buffer[256];
  332. sprintf_s(buffer, sizeof(buffer), "Type:%.2X ", pID[0]);
  333. str2 += buffer;
  334. if ((pID[0] & 0x80) == 0x80) // with TimeStamp
  335. {
  336. iIDLen = bPackLength - 7;
  337. }
  338. else
  339. iIDLen = bPackLength - 1;
  340. sprintf_s(buffer, sizeof(buffer), "Ant:%.2X Tag:", pID[1]);
  341. str2 += buffer;
  342. for (int i = 2; i < iIDLen; i++)
  343. {
  344. sprintf_s(buffer, sizeof(buffer), "%.2X", pID[i]);
  345. str2 += buffer;
  346. str2 += " ";
  347. tag += buffer;
  348. }
  349. sprintf_s(buffer, sizeof(buffer), "RSSI:%.2X", pID[iIDLen]);
  350. str2 += buffer;
  351. PrintLogMessage(str2);
  352. // Store the tag without spaces
  353. if (!tag.empty())
  354. {
  355. std::lock_guard<std::mutex> lock(instance->tags_mutex_);
  356. instance->tags_.insert(tag);
  357. }
  358. iLength = iLength + bPackLength + 1;
  359. }
  360. }
  361. void ReaderService::SendTagList()
  362. {
  363. if (data_callback_ && !tags_.empty())
  364. {
  365. // Convert the set of tags to a JSON string
  366. std::string tag_list_json = "[";
  367. bool first = true;
  368. for (const auto &tag : tags_)
  369. {
  370. if (!first)
  371. {
  372. tag_list_json += ",";
  373. }
  374. tag_list_json += "\"" + tag + "\"";
  375. first = false;
  376. }
  377. tag_list_json += "]";
  378. data_callback_(tag_list_json);
  379. }
  380. }
  381. ReaderService::~ReaderService()
  382. {
  383. // Disconnect during destruction
  384. Disconnect();
  385. }