|
@@ -0,0 +1,326 @@
|
|
|
+/*
|
|
|
+ * tcp_client.cpp
|
|
|
+ *
|
|
|
+ * Created on: 2022年10月5日
|
|
|
+ * Author: Allen
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+#include "tcp_client5084.h"
|
|
|
+
|
|
|
+#include "entry/EasyuiContext.h"
|
|
|
+#include "utils/Log.h"
|
|
|
+#include "utils/ByteUtil.h"
|
|
|
+#include "base/os.hpp"
|
|
|
+#include "base/strings.hpp"
|
|
|
+#include <system/Thread.h>
|
|
|
+#include <string>
|
|
|
+#include "net/NetManager.h"
|
|
|
+#include "service/BusinessConfig.h"
|
|
|
+
|
|
|
+static std::string sn = "";
|
|
|
+static byte code[4] = {0};
|
|
|
+static int dataConut = 0;
|
|
|
+
|
|
|
+#define ETHERNETMANAGER NETMANAGER->getEthernetManager()
|
|
|
+
|
|
|
+//异或校验 返回一个字节
|
|
|
+unsigned char CheckXor(const char *strData, int len)
|
|
|
+{
|
|
|
+ char checksum = 0;
|
|
|
+ for (int i = 0;i < len;i++)
|
|
|
+ {
|
|
|
+ checksum = checksum ^ strData[i];
|
|
|
+ }
|
|
|
+ return (unsigned char)checksum;
|
|
|
+}
|
|
|
+
|
|
|
+void handleMsg(byte* msg);
|
|
|
+
|
|
|
+TcpClient5084::TcpClient5084() {
|
|
|
+ busy_ = false;
|
|
|
+}
|
|
|
+
|
|
|
+TcpClient5084::~TcpClient5084() {
|
|
|
+}
|
|
|
+
|
|
|
+TcpClient5084* TcpClient5084::instance() {
|
|
|
+ static TcpClient5084 singleton;
|
|
|
+ return &singleton;
|
|
|
+}
|
|
|
+
|
|
|
+static net::Conn* conn;
|
|
|
+void TcpClient5084::sendMsg(byte* msg, int size){
|
|
|
+ instance()->internalSendMsg(msg, size);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void TcpClient5084::internalSendMsg(byte* msg, int size){
|
|
|
+ if (busy_) {
|
|
|
+ LOGD("TcpClient5084 client is busy");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ busy_ = true;
|
|
|
+ if (conn){
|
|
|
+ conn->Write(msg, size);
|
|
|
+
|
|
|
+// char _buf[1024];
|
|
|
+// std::string msgStr = "";
|
|
|
+// for (int i = 0; i < size; ++i) {
|
|
|
+// sprintf(_buf, "%02x", msg[i]);
|
|
|
+// msgStr += _buf;
|
|
|
+// }
|
|
|
+//
|
|
|
+// LOGD("TcpClient5084 sended msg : %s", msgStr.c_str());
|
|
|
+ } else {
|
|
|
+ LOGD("tcp disconnect");
|
|
|
+ }
|
|
|
+ busy_ = false;
|
|
|
+}
|
|
|
+
|
|
|
+static bool isLogin = false;
|
|
|
+static bool isWhile = true;
|
|
|
+class SleepThread: public Thread {
|
|
|
+public:
|
|
|
+ /**
|
|
|
+ * 线程创建成功后会调用该函数,可以在该函数中做一些初始化操作
|
|
|
+ * return true 继续线程
|
|
|
+ * false 退出线程
|
|
|
+ */
|
|
|
+ virtual bool readyToRun() {
|
|
|
+ LOGD("Thread 已经创建完成");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 线程循环函数
|
|
|
+ *
|
|
|
+ * return true 继续线程循环
|
|
|
+ * false 推出线程
|
|
|
+ */
|
|
|
+ virtual bool threadLoop() {
|
|
|
+ LOGD("线程循环函数");
|
|
|
+
|
|
|
+ //检查是否有退出线程的请求,如果有,则返回false,立即退出线程
|
|
|
+ if (exitPending()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ conn = net::Dial("tcp", "192.168.1.199:5084");
|
|
|
+ if (conn) {
|
|
|
+ byte buf[1024] = {0};
|
|
|
+
|
|
|
+ int v0;
|
|
|
+ std::string _dataCount = std::to_string(dataConut);
|
|
|
+ sscanf(_dataCount.c_str(), "%2X", &v0);
|
|
|
+
|
|
|
+ byte loginData[12] = {0};
|
|
|
+ loginData[0] = 0x82;
|
|
|
+ loginData[1] = 0x0A;
|
|
|
+ loginData[2] = 0x01;
|
|
|
+ loginData[3] = v0;
|
|
|
+ loginData[4] = 0x03;
|
|
|
+
|
|
|
+ for (int i = 0; i < sn.size(); i += 2) {
|
|
|
+ std::string snStr = sn.substr(i, 2);
|
|
|
+ sscanf(snStr.c_str(), "%2X", &v0);
|
|
|
+ loginData[5 + i/2] = v0;
|
|
|
+ }
|
|
|
+ loginData[11] = CheckXor((char*) loginData, 11);
|
|
|
+ TcpClient5084::instance()->sendMsg(loginData, 12);
|
|
|
+ isWhile = true;
|
|
|
+ dataConut += 1;
|
|
|
+
|
|
|
+ while (isWhile && !exitPending()) {
|
|
|
+ //读取,超时1000毫秒
|
|
|
+ int n = conn->Read(buf, sizeof(buf) - 1, 1000);
|
|
|
+ if (n > 0) {
|
|
|
+ buf[n] = 0;
|
|
|
+ char _buf[1024];
|
|
|
+
|
|
|
+ if (buf[4] == 0x03) {
|
|
|
+ code[0] = buf[5];
|
|
|
+ code[1] = buf[6];
|
|
|
+ code[2] = buf[7];
|
|
|
+ code[3] = buf[8];
|
|
|
+ isLogin = true;
|
|
|
+ }
|
|
|
+ } else if (n == 0) {
|
|
|
+ LOGD("连接正常断开");
|
|
|
+ isLogin = false;
|
|
|
+ isWhile = false;
|
|
|
+ break;
|
|
|
+ } else if (n == net::E_TIMEOUT) {
|
|
|
+// LOGD("读取超时");
|
|
|
+ } else {
|
|
|
+ LOGD("出错");
|
|
|
+ isLogin = false;
|
|
|
+ isWhile = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //关闭连接
|
|
|
+ conn->Close();
|
|
|
+ //释放内存
|
|
|
+ delete conn;
|
|
|
+ conn = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ //休眠5s
|
|
|
+ usleep(5000 * 1000);
|
|
|
+ //返回真,继续下次线程循环
|
|
|
+ return isLogin;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static SleepThread sleep_thread;
|
|
|
+
|
|
|
+void TcpClient5084::dataParse(std::string data) {
|
|
|
+// LOGD("data =================> %s", data.c_str());
|
|
|
+ if (data.substr(2, 2) == "0f") {
|
|
|
+ // cd0f0076000004643320504168100064e401a601e301a501df01a501e601a601e101a501e101a401e401a601e301a401e401a301e401a401e101a601e201a501e301a301e401a401e101a401df01a401e301a501e301a501e201a401e401a401e101a401e101a501e201a301e201a501e201a3015631303032dc
|
|
|
+
|
|
|
+ sn = data.substr(16, 12);
|
|
|
+ if (!isLogin) {
|
|
|
+ TcpClient5084::instance()->startTcp();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isLogin) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+// int v0;
|
|
|
+// std::string _dataCount = std::to_string(dataConut);
|
|
|
+// sscanf(_dataCount.c_str(), "%2X", &v0);
|
|
|
+
|
|
|
+ byte secondData[2048] = {0};
|
|
|
+ secondData[0] = 0x82;
|
|
|
+ secondData[1] = 0x16;
|
|
|
+ secondData[2] = 0x01;
|
|
|
+ secondData[3] = ByteUtil::stringToByte(std::to_string(dataConut));
|
|
|
+ secondData[4] = 0x0E;
|
|
|
+
|
|
|
+ time_t date = time(NULL);
|
|
|
+ std::string dateStr = ByteUtil::timestampToHex(date - (8 * 3600));
|
|
|
+ for (int i = 0; i < dateStr.size(); i += 2) {
|
|
|
+ std::string _dateStr = dateStr.substr(i, 2);
|
|
|
+ secondData[5 + i/2] = ByteUtil::stringToByte(_dateStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string healthyData = "";
|
|
|
+ // 心率
|
|
|
+ healthyData = data.substr(8, 2);
|
|
|
+ secondData[9] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 呼吸
|
|
|
+ healthyData = data.substr(10, 2);
|
|
|
+ secondData[10] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 状态
|
|
|
+ healthyData = data.substr(12, 2);
|
|
|
+ secondData[11] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 电量
|
|
|
+ healthyData = data.substr(14, 2);
|
|
|
+ secondData[12] = ByteUtil::stringToByte(healthyData);
|
|
|
+
|
|
|
+ for (int i = 0; i < sn.size(); i += 2) {
|
|
|
+ std::string snStr = sn.substr(i, 2);
|
|
|
+ secondData[13 + i/2] = ByteUtil::stringToByte(snStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ secondData[19] = code[0];
|
|
|
+ secondData[20] = code[1];
|
|
|
+ secondData[21] = code[2];
|
|
|
+ secondData[22] = code[3];
|
|
|
+
|
|
|
+ secondData[23] = CheckXor((char*) secondData, 23);
|
|
|
+
|
|
|
+ TcpClient5084::instance()->sendMsg(secondData, 24);
|
|
|
+ }
|
|
|
+ else if (data.substr(2, 2) == "3e") {
|
|
|
+ //cd3e000c620b0664013320504168108f
|
|
|
+// LOGD("=========================> 每分钟传输");
|
|
|
+
|
|
|
+ sn = data.substr(18, 12);
|
|
|
+ if (!isLogin) {
|
|
|
+ TcpClient5084::instance()->startTcp();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isLogin) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte secondData[2048] = {0};
|
|
|
+ secondData[0] = 0x82;
|
|
|
+ secondData[1] = 0x17;
|
|
|
+ secondData[2] = 0x01;
|
|
|
+ secondData[3] = ByteUtil::stringToByte(std::to_string(dataConut));
|
|
|
+ secondData[4] = 0x4E;
|
|
|
+
|
|
|
+ time_t date = time(NULL);
|
|
|
+ std::string dateStr = ByteUtil::timestampToHex(date - (8 * 3600));
|
|
|
+ for (int i = 0; i < dateStr.size(); i += 2) {
|
|
|
+ std::string _dateStr = dateStr.substr(i, 2);
|
|
|
+ secondData[5 + i/2] = ByteUtil::stringToByte(_dateStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string healthyData = "";
|
|
|
+ // 心率
|
|
|
+ healthyData = data.substr(8, 2);
|
|
|
+ secondData[9] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 呼吸
|
|
|
+ healthyData = data.substr(10, 2);
|
|
|
+ secondData[10] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 状态
|
|
|
+ healthyData = data.substr(12, 2);
|
|
|
+ secondData[11] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 电量
|
|
|
+ healthyData = data.substr(14, 2);
|
|
|
+ secondData[12] = ByteUtil::stringToByte(healthyData);
|
|
|
+ // 睡眠分层
|
|
|
+ healthyData = data.substr(16, 2);
|
|
|
+ secondData[13] = ByteUtil::stringToByte(healthyData);
|
|
|
+
|
|
|
+ for (int i = 0; i < sn.size(); i += 2) {
|
|
|
+ std::string snStr = sn.substr(i, 2);
|
|
|
+ secondData[14 + i/2] = ByteUtil::stringToByte(snStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ secondData[20] = code[0];
|
|
|
+ secondData[21] = code[1];
|
|
|
+ secondData[22] = code[2];
|
|
|
+ secondData[23] = code[3];
|
|
|
+
|
|
|
+ secondData[24] = CheckXor((char*) secondData, 24);
|
|
|
+
|
|
|
+ TcpClient5084::instance()->sendMsg(secondData, 25);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ dataConut += 1;
|
|
|
+ if (dataConut >= 255) {
|
|
|
+ dataConut = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+// std::string sn = data.substr(16, 29);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void TcpClient5084::startTcp(){
|
|
|
+ //调用线程类的run函数启动线程, 参数为线程名,可以任意指定。
|
|
|
+ sleep_thread.run("tcp thread");
|
|
|
+}
|
|
|
+
|
|
|
+void TcpClient5084::closeTcp() {
|
|
|
+ bool result = sleep_thread.isRunning();
|
|
|
+ if (result) {
|
|
|
+ sleep_thread.requestExitAndWait();
|
|
|
+ LOGD("my_thread已关闭");
|
|
|
+ }
|
|
|
+// my_thread.requestExit();
|
|
|
+}
|
|
|
+
|
|
|
+bool TcpClient5084::busy() {
|
|
|
+ return instance()->busy_;
|
|
|
+}
|
|
|
+
|
|
|
+bool TcpClient5084::connected() {
|
|
|
+ return conn != NULL;
|
|
|
+}
|