diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..afdc5d4
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,52 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.xinyingpower.testcomm"
+ minSdk 28
+ targetSdk 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ externalNativeBuild {
+ cmake {
+ cppFlags '-std=c++17'
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ externalNativeBuild {
+ cmake {
+ path file('src/main/cpp/CMakeLists.txt')
+ version '3.18.1'
+ }
+ }
+ buildFeatures {
+ viewBinding true
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.3.0'
+ implementation 'com.google.android.material:material:1.4.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..44bbb0d
--- /dev/null
+++ b/app/src/androidTest/java/com/xinyingpower/testcomm/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.xinyingpower.testcomm;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.xinyingpower.testcomm", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6aed52f
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/WeatherComm.cpp b/app/src/main/WeatherComm.cpp
new file mode 100644
index 0000000..9a2a648
--- /dev/null
+++ b/app/src/main/WeatherComm.cpp
@@ -0,0 +1,558 @@
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "GPIOControl.h"
+#include "WeatherComm.h"
+#include
+
+SIO_PARAM_SERIAL_DEF serialport;
+float weatherpntmsg[10];
+
+static void set_baudrate (struct termios *opt, unsigned int baudrate)
+{
+ cfsetispeed(opt, baudrate);
+ cfsetospeed(opt, baudrate);
+}
+
+static void set_data_bit (struct termios *opt, unsigned int databit)
+{
+ opt->c_cflag &= ~CSIZE;
+ switch (databit)
+ {
+ case 8:
+ opt->c_cflag |= CS8;
+ break;
+ case 7:
+ opt->c_cflag |= CS7;
+ break;
+ case 6:
+ opt->c_cflag |= CS6;
+ break;
+ case 5:
+ opt->c_cflag |= CS5;
+ break;
+ default:
+ opt->c_cflag |= CS8;
+ break;
+ }
+}
+
+static void set_parity (struct termios *opt, char parity)
+{
+ switch (parity)
+ {
+ case'N':/* 无校验 */
+ case 'n':
+ opt->c_cflag &= ~PARENB;
+ break;
+ case'E':/*偶校验*/
+ case 'e':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag &= ~PARODD;
+ break;
+ case'O':/* 奇校验 */
+ case 'o':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag |= ~PARODD;
+ break;
+ default: /*其它选择为无校验 */
+ opt->c_cflag &= ~PARENB;
+ break;
+ }
+}
+
+static void set_stopbit (struct termios *opt, const char *stopbit)
+{
+ if (strcmp(stopbit, "1") == 0)
+ {
+ opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */
+ }
+ else if(0 == strcmp(stopbit, "1.5"))
+ {
+ opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */
+ }
+ else if(0 == strcmp (stopbit,"2"))
+ {
+ opt->c_cflag |= CSTOPB; /*2 位停止位 */
+ }
+ else
+ {
+ opt->c_cflag &= ~CSTOPB; /*1 位停止位 */
+ }
+}
+
+int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin )
+{
+ struct termios opt;
+ tcgetattr(fd, &opt);
+ set_baudrate(&opt, baudrate);
+ //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */
+ opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG);
+ set_data_bit(&opt, databit);
+ set_parity(&opt, parity);
+ set_stopbit(&opt, stopbit);
+ opt.c_oflag = 0;
+ //opt.c_lflag |= 0;
+ opt.c_oflag &= ~OPOST;
+ opt.c_cc[VTIME] = vtime;
+ opt.c_cc[VMIN] = vmin;
+ tcflush (fd, TCIFLUSH);
+ return (tcsetattr (fd, TCSANOW, &opt));
+}
+
+static void setInt(int cmd, int value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value = value;
+ // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
+ if( fd > 0 )
+ {
+ int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+ close(fd);
+ }
+ return;
+}
+static void setRS485Enable(bool z) {
+ setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
+}
+
+static void set485WriteMode() {
+ setInt(CMD_SET_485_STATE, 1);
+}
+
+static void set485ReadMode() {
+ setInt(CMD_SET_485_STATE, 0);
+}
+static void set12VEnable(bool z) {
+ setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
+}
+
+static void setCam3V3Enable(bool enabled)
+{
+ setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
+}
+
+
+/*********************************************************************************
+* 气象数据处理 *
+**********************************************************************************/
+void PortDataProcess( void )
+{
+ float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
+ //WORD uDevAddr;
+ unsigned char cmdidx;
+ int i, j, aipnt, datanum;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+ char szbuf[64];
+
+ pPortParam = &serialport;
+ //取出装置地址,开始处理地址+++
+ if(0x02 == pPortParam->m_au8RecvBuf[5])
+ {
+ //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4];
+ return;
+ }
+ cmdidx = pPortParam->m_au8RecvBuf[5];
+#if 0
+ aipnt = pPortParam->SameTypeDevIdx;
+ uDevAddr = serialport->m_au8RecvBuf[4];
+ if(0 == srdt.IsReadWireTem)
+ {
+ if(uDevAddr != pPortParam->devaddr)
+ return;
+ }
+#endif
+ fvalua = &fvalue;
+ datanum = pPortParam->m_au8RecvBuf[6];
+ if((0x08 != cmdidx) && (0x09 != cmdidx))
+ return;
+
+ for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 )
+ {
+ if(0x08 == cmdidx)
+ fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16)
+ +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4];
+ else
+ {
+ *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4];
+ *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3];
+ *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2];
+ *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1];
+ }
+ switch(pPortParam->m_au8RecvBuf[j])
+ {
+ case 1: /*温度*/
+ weatherpntmsg[0] = fvalue;
+ LOGE("温度:%0.3f ", fvalue);
+ break;
+ case 2: /*气压*/
+ weatherpntmsg[5] = fvalue;
+ LOGE("气压:%0.3f ", fvalue);
+ break;
+ case 3: /*湿度*/
+ weatherpntmsg[1] = fvalue;
+ LOGE("湿度:%0.3f ", fvalue);
+ break;
+ case 4: /*雨量*/
+ break;
+ case 5: /*日照*/
+ break;
+ case 6: /*风速*/
+ weatherpntmsg[2] = fvalue;
+ LOGE("风速:%0.3f ", fvalue);
+ break;
+ case 7: /*风向*/
+ weatherpntmsg[3] = fvalue;
+ LOGE("风向:%0.3f ", fvalue);
+ break;
+ case 8: /*拉力*/
+ case 9: /*倾角传感器X轴倾角*/
+ case 10: /*倾角传感器Y轴倾角*/
+ case 11: /*测温球导线温度*/
+ case 12: /*测温球内部温度*/
+ break;
+ case 13: /*测温球导线X轴倾角*/
+ break;
+ case 14: /*测温球导线Y轴倾角*/
+ break;
+ case 15: /*测温球导线电流*/
+ break;
+ case 16: /*测温球电池电压*/
+ break;
+ case 17: /*A相泄漏电流平均值;*/
+ break;
+ case 18: /*A相泄漏电流最大值;*/
+ break;
+ case 19: /*A相超过3mA的脉冲频次*/
+ break;
+ case 20: /*A相超过10mA的脉冲频次*/
+ break;
+ case 21: /*B相泄漏电流平均值;*/
+ break;
+ case 22: /*B相泄漏电流最大值;*/
+ break;
+ case 23: /*B相超过3mA的脉冲频次*/
+ break;
+ case 24: /*B相超过10mA的脉冲频次*/
+ case 25: /*C相泄漏电流平均值;*/
+ case 26: /*C相泄漏电流最大值;*/
+ case 27: /*C相超过3mA的脉冲频次*/
+ case 28: /*C相超过10mA的脉冲频次*/
+ break;
+ }
+ }
+}
+
+//***************************************************************
+//* 按照协议格式化接收数据 *
+//***************************************************************
+static void RecvData(u_char *buf, int len)// 规约读数据处理
+{
+ int i, ictime;
+ //WORD crc, check;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ pPortParam = &serialport;
+ ictime = (int)time(NULL);
+
+ if(pPortParam->m_iRecvLen == 0)
+ {
+ pPortParam->iRecvTime = ictime;
+ }
+ else
+ {
+ if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0))
+ pPortParam->iRecvTime = ictime;
+ else if(ictime - pPortParam->iRecvTime > 2)
+ {
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_iRevStatus = 0;
+ }
+ }
+
+ for(i=0; im_iRevStatus)
+ {
+ case 0: // 0x68
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 1: // len1
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ break;
+ case 2: // len2
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2])
+ {
+ pPortParam->m_iRevStatus++;
+ pPortParam->m_iNeedRevLength = buf[i]+5;
+ }
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 3: // 0x68
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iNeedRevLength--;
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 4: // 正确接收数据
+ pPortParam->m_iNeedRevLength--;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iNeedRevLength > 0)
+ break;
+ if(buf[i] != 0x16)
+ {
+ pPortParam->m_iRevStatus=18;
+ break;
+ }
+
+ //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE)
+ {
+ PortDataProcess();
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->RevCmdFlag = 1;
+ }
+ pPortParam->m_iRecvLen = 0;
+ break;
+ case 255:// 错误接收数据
+ default:
+ if(buf[i] == 0x68)
+ {
+ pPortParam->m_iRevStatus = 1;
+ pPortParam->m_iRecvLen = 1;
+ pPortParam->m_au8RecvBuf[0] = buf[i];
+ }
+ else if(buf[i] == 0x16)
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->m_iRecvLen = 0;
+ }
+ else
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iRecvLen > 200)
+ {
+ pPortParam->m_iRecvLen = 0;
+ }
+ }
+ break;
+ }
+ }
+}
+
+static long get_msec(void )
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ long time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000;
+
+ return time_in_msec;
+}
+//int inum =0;
+//int itimecnt=0;
+static int weather_comm(SERIAL_PARAM weatherport)
+{
+ int fd = -1;
+ int len, i,ret, icnt=0;
+ long ictime, iruntime, isendtime, irecvtime;
+ unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16};
+ char recvbuf[256], szbuf[512];
+ //char serial_description[] = "/dev/ttyS0";
+
+#if 0
+ DIR *dir = opendir("/dev");
+ if (dir == NULL) {
+ LOGE("_test_ opendir");
+ return -1;
+ }
+
+ // 读取目录项
+ struct dirent *entry;
+ while ((entry = readdir(dir)) != NULL) {
+ // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头
+ if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
+ (strncmp(entry->d_name, "ttyS0", 5) == 0)) {
+ LOGE("_test_ Found serial port: %s\n", entry->d_name);
+ }
+ }
+
+ // 关闭目录
+ closedir(dir);
+#endif
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+
+ set12VEnable(true);
+ setCam3V3Enable(true);
+ setRS485Enable(true);
+ sleep(2);
+ //ictime = (int)time(NULL);
+ ictime = get_msec();
+ for(;;)
+ {
+ if(fd < 0)
+ {
+ fd = open(weatherport.pathname, O_RDWR | O_NDELAY);
+ //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY);
+ if(fd < 0)
+ {
+ LOGE("_test_ open serial error \n");
+ perror(weatherport.pathname);
+ return -1;
+ }
+
+ ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */
+ if(ret < 0)
+ {
+ LOGE("_test_ set uart arrt faile \n");
+ return -1;
+ }
+ }
+
+ usleep(10000);
+ //iruntime = (int)time(NULL);
+ iruntime = get_msec();
+ if((iruntime - ictime > 120000) || (iruntime - ictime < 0))
+ ictime = iruntime;
+ if(iruntime - ictime > 20000)
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0);
+ LOGE("%s", szbuf);
+ break;
+ }
+
+ if(1 == serialport.RevCmdFlag)
+ {
+ set485WriteMode();
+
+ len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
+ serialport.RevCmdFlag = 0;
+ LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime);
+ //isendtime = time(NULL);
+ isendtime = get_msec();
+ if (len < 0) {
+ LOGE("write data error \n");
+ return -1;
+ } else {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Send:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]);
+ }
+ LOGE("%s", szbuf);
+ //icnt = 0;
+ //inum++;
+ }
+ tcdrain(fd);
+ //usleep(50000);
+ }
+ else
+ {
+ //irecvtime = time(NULL);
+ irecvtime = get_msec();
+ if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0))
+ isendtime = irecvtime;
+ if (irecvtime-isendtime > 300)
+ {
+ LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime);
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+ close(fd);
+ //set12VEnable(false);
+ //setCam3V3Enable(false);
+ //setRS485Enable(false);
+ fd = -1;
+ continue;
+ }
+ }
+ set485ReadMode();
+ memset(recvbuf, 0, sizeof(recvbuf));
+ len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */
+ if (len < 0) {
+ LOGE("serial read error \n");
+ continue;
+ }
+ if(0 == len)
+ {
+ //icnt++;
+ continue;
+ }
+
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Recv:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]);
+ }
+ __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf);
+ RecvData((u_char*)recvbuf, len);
+ //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt);
+ icnt = 0;
+ //serialport.RevCmdFlag =1;
+ }
+
+ close(fd);
+ set12VEnable(false);
+ setCam3V3Enable(false);
+ setRS485Enable(false);
+
+ //exit(-1);
+ return(0);
+}
+
+int serial_port_comm()
+{
+ SERIAL_PARAM portparm;
+
+ //struct timeval tv;
+
+ //gettimeofday(&tv, NULL);
+ //long time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec;
+
+ //LOGE("Current time in microseconds: %ld\n", time_in_microseconds);
+
+#if 1
+ memset(portparm.pathname, 0, sizeof(portparm.pathname));
+ sprintf(portparm.pathname, "/dev/ttyS0");
+ portparm.parity = 'N';
+ portparm.databit = 8;
+ portparm.baudrate = B9600;
+ memset(portparm.stopbit, 0, sizeof(portparm.stopbit));
+ sprintf(portparm.stopbit, "1");
+#endif
+ //itimecnt = (int)time(NULL);
+
+ //for(;;)
+ weather_comm(portparm);
+ return 0;
+}
+
diff --git a/app/src/main/WeatherComm.h b/app/src/main/WeatherComm.h
new file mode 100644
index 0000000..80c47f9
--- /dev/null
+++ b/app/src/main/WeatherComm.h
@@ -0,0 +1,51 @@
+//
+// Created by hyz on 2024/6/5.
+//
+
+#ifndef WEATHERCOMM_H
+#define WEATHERCOMM_H
+
+#include
+#include "GPIOControl.h"
+
+#define MAX_STRING_LEN 32
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+
+#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args)
+
+// 串口参数
+typedef struct
+{
+ int baudrate; /* 波特率*/
+ int databit; /* 数据位*/
+ char stopbit[8]; /* 停止位*/
+ char parity; /* 校验位*/
+ char pathname[128];/* 串口文件名及路径*/
+} SERIAL_PARAM;
+
+typedef struct
+{
+ int m_iRevStatus; /* */
+ int m_iRecvLen; /* */
+ int m_iNeedRevLength; /* */
+ int iRecvTime; /* */
+ int RevCmdFlag;
+ unsigned char m_au8RecvBuf[128];/* */
+} SIO_PARAM_SERIAL_DEF;
+
+typedef struct
+{
+ int cmd;
+ int value;
+ int result;
+ long value2;
+ char str[MAX_STRING_LEN];
+}IOT_PARAM;
+
+void PortDataProcess( void );
+int serial_port_comm();
+static int weather_comm(SERIAL_PARAM weatherport);
+int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin );
+
+#endif //WEATHERCOMM_H
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..4015c24
--- /dev/null
+++ b/app/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,60 @@
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html
+
+# Sets the minimum version of CMake required to build the native library.
+
+cmake_minimum_required(VERSION 3.18.1)
+
+# Declares and names the project.
+
+project("testcomm")
+
+# Creates and names a library, sets it as either STATIC
+# or SHARED, and provides the relative paths to its source code.
+# You can define multiple libraries, and CMake builds them for you.
+# Gradle automatically packages shared libraries with your APK.
+
+add_library( # Sets the name of the library.
+ testcomm
+
+ # Sets the library as a shared library.
+ SHARED
+
+ # Provides a relative path to your source file(s).
+ SpiPort.cpp
+ #spi-test-random.cpp
+ # NRSEC3000ctl.cpp
+ SpiLib.cpp
+ native-lib.cpp
+ GPIOControl.cpp
+ #WeatherComm.cpp
+ serialComm.cpp
+ SensorsProtocol.cpp
+ )
+
+# Searches for a specified prebuilt library and stores the path as a
+# variable. Because CMake includes system libraries in the search path by
+# default, you only need to specify the name of the public NDK library
+# you want to add. CMake verifies that the library exists before
+# completing its build.
+
+find_library( # Sets the name of the path variable.
+ log-lib
+
+ # Specifies the name of the NDK library that
+ # you want CMake to locate.
+
+ log)
+
+# Specifies libraries CMake should link to your target library. You
+# can link multiple libraries, such as libraries you define in this
+# build script, prebuilt third-party libraries, or system libraries.
+
+target_link_libraries( # Specifies the target library.
+ testcomm
+
+ android
+
+ # Links the target library to the log library
+ # included in the NDK.
+ ${log-lib})
\ No newline at end of file
diff --git a/app/src/main/cpp/GPIOControl.cpp b/app/src/main/cpp/GPIOControl.cpp
new file mode 100644
index 0000000..783025a
--- /dev/null
+++ b/app/src/main/cpp/GPIOControl.cpp
@@ -0,0 +1,144 @@
+//
+// Created by Matthew on 2023/12/27.
+//
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "GPIOControl.h"
+
+#ifdef _DEBUG
+#include
+#endif
+
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+#define MAX_STRING_LEN 32
+
+typedef struct
+{
+ int cmd;
+ int value;
+ int result;
+ long value2;
+ char str[MAX_STRING_LEN];
+}IOT_PARAM;
+
+typedef struct{
+ float airtemp; /* 空气温度*/
+ float RH; /* 相对湿度*/
+ float atmos; /* 大气压*/
+ float windspeed; /* 风速*/
+ float winddirection; /* 风向*/
+ float rainfall; /* 雨量*/
+ float sunshine; /* 日照*/
+}Weather;
+
+void GpioControl::setInt(int cmd, int value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value = value;
+ // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
+ if( fd > 0 )
+ {
+ int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+ close(fd);
+ }
+ return;
+}
+
+int GpioControl::getInt(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+#ifdef _DEBUG
+ ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+#endif
+ close(fd);
+ return param.value;
+ }
+ return -1;
+}
+
+void GpioControl::setLong(int cmd, long value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value2 = value;
+ // LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2);
+
+ if( fd > 0 )
+ {
+ ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
+ close(fd);
+ }
+}
+
+long GpioControl::getLong(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+ // LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
+ close(fd);
+ return param.value2;
+ }
+ return -1;
+}
+
+void GpioControl::setString(int cmd, const std::string& value)
+{
+ IOT_PARAM param;
+ // char *pval = jstringToChars(env, value);
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
+
+ param.cmd = cmd;
+ memset(param.str, 0, MAX_STRING_LEN);
+ memcpy(param.str, value.c_str(), len);
+ // LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
+ if( fd > 0 )
+ {
+ ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
+ close(fd);
+ }
+ return;
+}
+
+std::string GpioControl::getString(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+ // LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
+ close(fd);
+ return std::string(param.str);
+ }
+ return "";
+}
diff --git a/app/src/main/cpp/GPIOControl.h b/app/src/main/cpp/GPIOControl.h
new file mode 100644
index 0000000..8bb0a5a
--- /dev/null
+++ b/app/src/main/cpp/GPIOControl.h
@@ -0,0 +1,205 @@
+//
+// Created by Matthew on 2023/12/27.
+//
+
+#ifndef MICROPHOTO_GPIOCONTROL_H
+#define MICROPHOTO_GPIOCONTROL_H
+
+#include
+
+#define CMD_GET_LIGHT_ADC 101
+#define CMD_SET_LIGHT_ADC 102
+#define CMD_GET_KEY_LOCKSTATE 103
+#define CMD_GET_BAT_ADC 104
+#define CMD_SET_FLASH_LED 105
+#define CMD_SET_NETWORK_STATE 106
+#define CMD_SET_OTG_STATE 107
+#define CMD_GET_OTG_STATE 108
+#define CMD_GET_CHARGING_VOL_STATE 110
+#define CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE 111
+#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112
+#define CMD_GET_CHARGING_POWER_STATE 113
+#define CMD_GET_CHARGING_CURRENT_STATE 114
+#define CMD_GET_BAT_VOL_STATE 115
+#define CMD_GET_BAT_SHUNT_VOLTAGE_STATE 116
+#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117
+#define CMD_GET_BAT_POWER_STATE 118
+#define CMD_GET_BAT_CURRENT_STATE 119
+#define CMD_SET_485_STATE 121
+#define CMD_SET_SPI_MODE 123
+#define CMD_SET_SPI_BITS_PER_WORD 124
+#define CMD_SET_SPI_MAXSPEEDHZ 125
+#define CMD_SET_PWM_BEE_STATE 126
+#define CMD_SET_ALM_MODE 128
+#define CMD_SET_SPI_POWER 129
+#define CMD_SET_485_EN_STATE 131
+#define CMD_SET_CAM_3V3_EN_STATE 132
+#define CMD_SET_12V_EN_STATE 133
+#define CMD_SET_SYSTEM_RESET 202
+#define CMD_SET_WTH_POWER 490
+#define CMD_SET_PULL_POWER 491
+#define CMD_SET_ANGLE_POWER 492
+#define CMD_SET_OTHER_POWER 493
+#define CMD_SET_PIC1_POWER 494
+#define CMD_SET_485_en0 301
+#define CMD_SET_485_en1 302
+#define CMD_SET_485_en2 303
+#define CMD_SET_485_en3 304
+#define CMD_SET_485_en4 305
+
+#define CMD_SET_ADC_ENABLE 500
+#define CMD_SET_MIPI_SWITCH 501
+#define CMD_SET_CAM_RSTN1 502
+#define CMD_SET_CAM_RSTN0 503
+#define CMD_SET_SENSOR_ENABLE 504
+#define CMD_SET_SENSOR_PWR_ENABLE 505
+#define CMD_SET_SENSOR2_ENABLE 506
+#define CMD_SET_SD_DECT 507
+#define CMD_SET_PTZ_PWR_ENABLE 508
+#define CMD_SET_SENSOR3_PWR_ENABLE 509
+#define CMD_SET_SENSOR4_ENABLE 510
+#define CMD_SET_RTC_ENABLE 511
+#define CMD_SET_485_ENABLE 512
+#define CMD_SET_SENSOR1_PWR_ENABLE 513
+#define CMD_SET_SENSOR2_PWR_ENABLE 514
+#define CMD_SET_PHOTO_OUT 515
+#define CMD_SET_3V3_PWR_ENABLE 516
+#define CMD_SET_5V_PWR_ENABLE 517
+#define CMD_SET_100M_ENABLE 518
+#define CMD_SET_100M_SWITCH_PWR_ENABLE 519
+#define CMD_SET_PHOTO_IN 520
+#define CMD_SET_AM_POWER_ENABLE 521
+#define CMD_SET_NRSEC_POWER_ENABLE 522
+#define CMD_SET_AMP_ENABLE 523
+#define CMD_SET_LIGHT1_RESISTOR_ENABLE 524
+#define CMD_SET_SENSOR4_PWR_ENABLE 525
+#define CMD_SET_100M_RESET 526
+
+class GpioControl
+{
+public:
+
+ static void setInt(int cmd, int value);
+ static int getInt(int cmd);
+ static void setLong(int cmd, long value);
+ static long getLong(int cmd);
+ static void setString(int cmd, const std::string& value);
+ static std::string getString(int cmd);
+
+ static void setOtgState(bool on)
+ {
+ setInt(CMD_SET_OTG_STATE, on ? 1 : 0);
+ }
+
+ static bool getOtgState()
+ {
+ return getInt(CMD_SET_OTG_STATE) != 0;
+ }
+
+ static void setCam3V3Enable(bool enabled)
+ {
+ setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
+ }
+
+ static void reboot()
+ {
+ setInt(CMD_SET_SYSTEM_RESET, 1);
+ }
+
+ static void setLightAdc(int i)
+ {
+ setInt(CMD_SET_LIGHT_ADC, i);
+ }
+
+ static int getLightAdc()
+ {
+ return getInt(CMD_GET_LIGHT_ADC);
+ }
+
+ static int getChargingVoltage()
+ {
+ return getInt(CMD_GET_CHARGING_VOL_STATE);
+ }
+
+ static int getChargingShuntVoltage()
+ {
+ return getInt(CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE);
+ }
+
+ static int getChargingBusVoltage() {
+ return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE);
+ }
+
+ static int getChargingPower() {
+ return getInt(CMD_GET_CHARGING_POWER_STATE);
+ }
+
+ static int getChargingCurrent() {
+ return getInt(CMD_GET_CHARGING_CURRENT_STATE);
+ }
+
+ static int getBatteryVoltage() {
+ return getInt(CMD_GET_BAT_VOL_STATE);
+ }
+
+ static int getBatteryShuntVoltage() {
+ return getInt(CMD_GET_BAT_SHUNT_VOLTAGE_STATE);
+ }
+
+ static int getBatteryBusVoltage() {
+ return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE);
+ }
+
+ static int getBatteryPower() {
+ return getInt(CMD_GET_BAT_POWER_STATE);
+ }
+
+ static int getBatteryCurrent() {
+ return getInt(CMD_GET_BAT_CURRENT_STATE);
+ }
+
+ static void set485WriteMode() {
+ setInt(CMD_SET_485_STATE, 1);
+ }
+
+ static void set485ReadMode() {
+ setInt(CMD_SET_485_STATE, 0);
+ }
+
+ static void setSpiMode(int i) {
+ setInt(CMD_SET_SPI_MODE, i);
+ }
+
+ static void setSpiBitsPerWord(int i) {
+ setInt(CMD_SET_SPI_BITS_PER_WORD, i);
+ }
+
+ static void setSpiMaxSpeedHz(long j) {
+ setLong(CMD_SET_SPI_MAXSPEEDHZ, j);
+ }
+
+ static void setBeeOn(bool z) {
+ setInt(CMD_SET_PWM_BEE_STATE, z ? 1 : 0);
+ }
+
+ static void setJidianqiState(bool z) {
+ setInt(CMD_SET_ALM_MODE, z ? 1 : 0);
+ }
+
+ static void setSpiPower(bool on) {
+ setInt(CMD_SET_SPI_POWER, on ? 1 : 0);
+ }
+
+ static void setRS485Enable(bool z) {
+ setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
+ }
+
+
+ static void set12VEnable(bool z) {
+ setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
+ }
+
+};
+
+
+#endif //MICROPHOTO_GPIOCONTROL_H
diff --git a/app/src/main/cpp/SensorsProtocol.cpp b/app/src/main/cpp/SensorsProtocol.cpp
new file mode 100644
index 0000000..b8cca27
--- /dev/null
+++ b/app/src/main/cpp/SensorsProtocol.cpp
@@ -0,0 +1,3759 @@
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+//#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "GPIOControl.h"
+#include "serialComm.h"
+#include "SensorsProtocol.h"
+#include
+#include "SensorsProtocol.h"
+//#include "Eint.h"
+
+SIO_PARAM_SERIAL_DEF serialport[MAX_SERIAL_PORT_NUM];
+SERIAL_PARAM devparam[MAX_SERIAL_DEV_NUM];
+SRDT_DEF srdt;
+AI_DEF weatherpntmsg[WEATHER_DATA_NUM];
+AI_DEF rallypntmsg[6][RALLY_DATA_NUM];
+AI_DEF slantpntmsg[6][SLANTANGLE_DATA_NUM];
+
+static void setInt(int cmd, int value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value = value;
+ // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
+ if( fd > 0 )
+ {
+ ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+ close(fd);
+ }
+ //return;
+}
+
+int getInt(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+#ifdef _DEBUG
+ ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+#endif
+ close(fd);
+ return param.value;
+ }
+ return -1;
+}
+
+static void setRS485Enable(bool z) {
+ setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
+}
+
+static void set485WriteMode() {
+ setInt(CMD_SET_485_STATE, 1);
+}
+
+static void set485ReadMode() {
+ setInt(CMD_SET_485_STATE, 0);
+}
+static void set12VEnable(bool z) {
+ setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
+}
+
+static void setCam3V3Enable(bool enabled)
+{
+ setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
+}
+
+#if 0
+/*********************************************************************************
+* 气象数据处理 *
+**********************************************************************************/
+static void PortDataProcess( void )
+{
+ float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
+ //WORD uDevAddr;
+ unsigned char cmdidx;
+ int i, j, aipnt, datanum;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+ char szbuf[64];
+
+ pPortParam = &serialport;
+ //取出装置地址,开始处理地址+++
+ if(0x02 == pPortParam->m_au8RecvBuf[5])
+ {
+ //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4];
+ return;
+ }
+ cmdidx = pPortParam->m_au8RecvBuf[5];
+#if 0
+ aipnt = pPortParam->SameTypeDevIdx;
+ uDevAddr = serialport->m_au8RecvBuf[4];
+ if(0 == srdt.IsReadWireTem)
+ {
+ if(uDevAddr != pPortParam->devaddr)
+ return;
+ }
+#endif
+ fvalua = &fvalue;
+ datanum = pPortParam->m_au8RecvBuf[6];
+ if((0x08 != cmdidx) && (0x09 != cmdidx))
+ return;
+
+ for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 )
+ {
+ if(0x08 == cmdidx)
+ fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16)
+ +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4];
+ else
+ {
+ *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4];
+ *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3];
+ *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2];
+ *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1];
+ }
+ switch(pPortParam->m_au8RecvBuf[j])
+ {
+ case 1: /*温度*/
+ weatherpntmsg[0] = fvalue;
+ LOGE("温度:%0.3f ", fvalue);
+ break;
+ case 2: /*气压*/
+ weatherpntmsg[5] = fvalue;
+ LOGE("气压:%0.3f ", fvalue);
+ break;
+ case 3: /*湿度*/
+ weatherpntmsg[1] = fvalue;
+ LOGE("湿度:%0.3f ", fvalue);
+ break;
+ case 4: /*雨量*/
+ break;
+ case 5: /*日照*/
+ break;
+ case 6: /*风速*/
+ weatherpntmsg[2] = fvalue;
+ LOGE("风速:%0.3f ", fvalue);
+ break;
+ case 7: /*风向*/
+ weatherpntmsg[3] = fvalue;
+ LOGE("风向:%0.3f ", fvalue);
+ break;
+ case 8: /*拉力*/
+ case 9: /*倾角传感器X轴倾角*/
+ case 10: /*倾角传感器Y轴倾角*/
+ case 11: /*测温球导线温度*/
+ case 12: /*测温球内部温度*/
+ break;
+ case 13: /*测温球导线X轴倾角*/
+ break;
+ case 14: /*测温球导线Y轴倾角*/
+ break;
+ case 15: /*测温球导线电流*/
+ break;
+ case 16: /*测温球电池电压*/
+ break;
+ case 17: /*A相泄漏电流平均值;*/
+ break;
+ case 18: /*A相泄漏电流最大值;*/
+ break;
+ case 19: /*A相超过3mA的脉冲频次*/
+ break;
+ case 20: /*A相超过10mA的脉冲频次*/
+ break;
+ case 21: /*B相泄漏电流平均值;*/
+ break;
+ case 22: /*B相泄漏电流最大值;*/
+ break;
+ case 23: /*B相超过3mA的脉冲频次*/
+ break;
+ case 24: /*B相超过10mA的脉冲频次*/
+ case 25: /*C相泄漏电流平均值;*/
+ case 26: /*C相泄漏电流最大值;*/
+ case 27: /*C相超过3mA的脉冲频次*/
+ case 28: /*C相超过10mA的脉冲频次*/
+ break;
+ }
+ }
+}
+
+/***************************************************************
+* 按照协议格式化接收数据 *
+***************************************************************/
+static void RecvData(u_char *buf, int len)// 规约读数据处理
+{
+ int i, ictime;
+ //WORD crc, check;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ pPortParam = &serialport;
+ ictime = (int)time(NULL);
+
+ if(pPortParam->m_iRecvLen == 0)
+ {
+ pPortParam->iRecvTime = ictime;
+ }
+ else
+ {
+ if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0))
+ pPortParam->iRecvTime = ictime;
+ else if(ictime - pPortParam->iRecvTime > 2)
+ {
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_iRevStatus = 0;
+ }
+ }
+
+ for(i=0; im_iRevStatus)
+ {
+ case 0: // 0x68
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 1: // len1
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ break;
+ case 2: // len2
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2])
+ {
+ pPortParam->m_iRevStatus++;
+ pPortParam->m_iNeedRevLength = buf[i]+5;
+ }
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 3: // 0x68
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iNeedRevLength--;
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 4: // 正确接收数据
+ pPortParam->m_iNeedRevLength--;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iNeedRevLength > 0)
+ break;
+ if(buf[i] != 0x16)
+ {
+ pPortParam->m_iRevStatus=18;
+ break;
+ }
+
+ //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE)
+ {
+ PortDataProcess();
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->RevCmdFlag = 1;
+ }
+ pPortParam->m_iRecvLen = 0;
+ break;
+ case 255:// 错误接收数据
+ default:
+ if(buf[i] == 0x68)
+ {
+ pPortParam->m_iRevStatus = 1;
+ pPortParam->m_iRecvLen = 1;
+ pPortParam->m_au8RecvBuf[0] = buf[i];
+ }
+ else if(buf[i] == 0x16)
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->m_iRecvLen = 0;
+ }
+ else
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iRecvLen > 200)
+ {
+ pPortParam->m_iRecvLen = 0;
+ }
+ }
+ break;
+ }
+ }
+}
+
+static LONG get_msec(void )
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ LONG time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000;
+
+ return time_in_msec;
+}
+//int inum =0;
+//int itimecnt=0;
+static int weather_comm(SERIAL_PARAM weatherport)
+{
+ int fd = -1;
+ int len, i,ret, icnt=0;
+ LONG ictime, iruntime, isendtime, irecvtime;
+ unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16};
+ char recvbuf[256], szbuf[512];
+ //char serial_description[] = "/dev/ttyS0";
+
+#if 0
+ DIR *dir = opendir("/dev");
+ if (dir == NULL) {
+ LOGE("_test_ opendir");
+ return -1;
+ }
+
+ // 读取目录项
+ struct dirent *entry;
+ while ((entry = readdir(dir)) != NULL) {
+ // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头
+ if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
+ (strncmp(entry->d_name, "ttyS0", 5) == 0)) {
+ LOGE("_test_ Found serial port: %s\n", entry->d_name);
+ }
+ }
+
+ // 关闭目录
+ closedir(dir);
+#endif
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+
+ set12VEnable(true);
+ setCam3V3Enable(true);
+ setRS485Enable(true);
+ sleep(2);
+ //ictime = (int)time(NULL);
+ ictime = get_msec();
+ for(;;)
+ {
+ if(fd < 0)
+ {
+ fd = open(weatherport.pathname, O_RDWR | O_NDELAY);
+ //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY);
+ if(fd < 0)
+ {
+ LOGE("_test_ open serial error \n");
+ perror(weatherport.pathname);
+ return -1;
+ }
+
+ ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */
+ if(ret < 0)
+ {
+ LOGE("_test_ set uart arrt faile \n");
+ return -1;
+ }
+ }
+
+ usleep(10000);
+ //iruntime = (int)time(NULL);
+ iruntime = get_msec();
+ if((iruntime - ictime > 120000) || (iruntime - ictime < 0))
+ ictime = iruntime;
+ if(iruntime - ictime > 20000)
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0);
+ LOGE("%s", szbuf);
+ break;
+ }
+
+ if(1 == serialport.RevCmdFlag)
+ {
+ set485WriteMode();
+
+ len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
+ serialport.RevCmdFlag = 0;
+ LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime);
+ //isendtime = time(NULL);
+ isendtime = get_msec();
+ if (len < 0) {
+ LOGE("write data error \n");
+ return -1;
+ } else {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Send:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]);
+ }
+ LOGE("%s", szbuf);
+ //icnt = 0;
+ //inum++;
+ }
+ tcdrain(fd);
+ //usleep(50000);
+ }
+ else
+ {
+ //irecvtime = time(NULL);
+ irecvtime = get_msec();
+ if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0))
+ isendtime = irecvtime;
+ if (irecvtime-isendtime > 300)
+ {
+ LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime);
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+ close(fd);
+ fd = -1;
+ continue;
+ }
+ }
+ set485ReadMode();
+ memset(recvbuf, 0, sizeof(recvbuf));
+ len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */
+ if (len < 0) {
+ LOGE("serial read error \n");
+ continue;
+ }
+ if(0 == len)
+ {
+ //icnt++;
+ continue;
+ }
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Recv:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]);
+ }
+ __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf);
+ RecvData((u_char*)recvbuf, len);
+ //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt);
+ icnt = 0;
+ //serialport.RevCmdFlag =1;
+ }
+
+ close(fd);
+ set12VEnable(false);
+ setCam3V3Enable(false);
+ setRS485Enable(false);
+
+ //exit(-1);
+ return(0);
+}
+
+int serial_port_comm()
+{
+ SERIAL_PARAM portparm;
+
+ //struct timeval tv;
+
+ //gettimeofday(&tv, NULL);
+ //LONG time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec;
+
+ //LOGE("Current time in microseconds: %ld\n", time_in_microseconds);
+
+#if 1
+ memset(portparm.pathname, 0, sizeof(portparm.pathname));
+ sprintf(portparm.pathname, "/dev/ttyS0");
+ portparm.parity = 'N';
+ portparm.databit = 8;
+ portparm.baudrate = B9600;
+ memset(portparm.stopbit, 0, sizeof(portparm.stopbit));
+ sprintf(portparm.stopbit, "1");
+#endif
+ //itimecnt = (int)time(NULL);
+
+ //for(;;)
+ weather_comm(portparm);
+ return 0;
+}
+#endif
+
+static speed_t getBaudrate(unsigned int baudrate)
+{
+ switch(baudrate) {
+ case 0: return B0;
+ case 50: return B50;
+ case 75: return B75;
+ case 110: return B110;
+ case 134: return B134;
+ case 150: return B150;
+ case 200: return B200;
+ case 300: return B300;
+ case 600: return B600;
+ case 1200: return B1200;
+ case 1800: return B1800;
+ case 2400: return B2400;
+ case 4800: return B4800;
+ case 9600: return B9600;
+ case 19200: return B19200;
+ case 38400: return B38400;
+ case 57600: return B57600;
+ case 115200: return B115200;
+ case 230400: return B230400;
+ case 460800: return B460800;
+ case 500000: return B500000;
+ case 576000: return B576000;
+ case 921600: return B921600;
+ case 1000000: return B1000000;
+ case 1152000: return B1152000;
+ case 1500000: return B1500000;
+ case 2000000: return B2000000;
+ case 2500000: return B2500000;
+ case 3000000: return B3000000;
+ case 3500000: return B3500000;
+ case 4000000: return B4000000;
+ default: return B9600;
+ }
+}
+
+static LONG get_msec()
+{
+ struct timeval tv;
+ LONG time_in_msec=0;
+
+ gettimeofday(&tv, NULL);
+ time_in_msec = tv.tv_sec;
+ time_in_msec *= 1000;
+ time_in_msec += tv.tv_usec/1000;
+
+ return time_in_msec;
+}
+
+/*
+打开串口电源
+*/
+void Gm_OpenSerialPower()
+{
+ /*由传送的主站的地方来控制串口电源,这里不实现*/;
+}
+
+// 关闭串口电源
+void Gm_CloseSerialPower()
+{
+}
+
+// 关闭传感器电源
+void Gm_CloseSensorsPower()
+{
+ //char iIoNo;
+ //char szbuf[128];
+ int igpio;
+
+ //sprintf(szbuf, "Close Sensors port %d Power!", port);
+
+ /* 关闭电源*/
+ //switch(port)
+ /* 根据硬件具体布置最后调整,目前是微拍板子的来控制*/
+ //set12VEnable(false);
+ //setCam3V3Enable(false);
+ //setRS485Enable(false);
+
+#if 0
+ setInt(CMD_SET_WTH_POWER, 0);
+ setInt(CMD_SET_PULL_POWER, 0);
+ setInt(CMD_SET_ANGLE_POWER, 0);
+ setInt(CMD_SET_OTHER_POWER, 0);
+ setInt(CMD_SET_PIC1_POWER, 0);
+
+ sleep(3);
+ igpio = getInt(CMD_SET_WTH_POWER);
+ igpio = getInt(CMD_SET_PULL_POWER);
+ igpio = getInt(CMD_SET_ANGLE_POWER);
+ igpio = getInt(CMD_SET_OTHER_POWER);
+ igpio = getInt(CMD_SET_PIC1_POWER);
+#endif
+#if 1
+ setInt(CMD_SET_SPI_POWER, 1);
+ setInt(CMD_SET_485_en0, 1);
+ setInt(CMD_SET_485_en1, 1);
+ setInt(CMD_SET_485_en2, 1);
+ setInt(CMD_SET_485_en3, 1);
+ setInt(CMD_SET_485_en4, 1);
+#else
+ setInt(CMD_SET_SPI_POWER, 0);
+ setInt(CMD_SET_485_en0, 0);
+ setInt(CMD_SET_485_en1, 0);
+ setInt(CMD_SET_485_en2, 0);
+ setInt(CMD_SET_485_en3, 0);
+ setInt(CMD_SET_485_en4, 0);
+ sleep(3);
+ igpio = getInt(CMD_SET_SPI_POWER);
+ igpio = getInt(CMD_SET_485_en0);
+ igpio = getInt(CMD_SET_485_en1);
+ igpio = getInt(CMD_SET_485_en2);
+ igpio = getInt(CMD_SET_485_en3);
+ igpio = getInt(CMD_SET_485_en4);
+#endif
+
+}
+
+// 打开传感器电源
+void Gm_OpenSensorsPower()
+{
+ //char iIoNo;
+ int igpio;
+ char szbuf[128];
+
+ //if(0 == port)
+ // return;
+ //sprintf(szbuf, "Open Sensors port %d Power!", port);
+
+ set12VEnable(true);
+ setCam3V3Enable(true);
+ setRS485Enable(true);
+ setInt(CMD_SET_485_ENABLE, 1); // 打开RS485电源
+ setInt(CMD_SET_3V3_PWR_ENABLE, 1); // 打开3.3V电压
+ setInt(CMD_SET_PTZ_PWR_ENABLE, 1);
+
+#if 0
+ setInt(CMD_SET_WTH_POWER, 0);
+ setInt(CMD_SET_PULL_POWER, 0);
+ setInt(CMD_SET_ANGLE_POWER, 0);
+ setInt(CMD_SET_OTHER_POWER, 0);
+ setInt(CMD_SET_PIC1_POWER, 0);
+#else
+ setInt(CMD_SET_WTH_POWER, 1);
+ setInt(CMD_SET_PULL_POWER, 1);
+ setInt(CMD_SET_ANGLE_POWER, 1);
+ setInt(CMD_SET_OTHER_POWER, 1);
+ setInt(CMD_SET_PIC1_POWER, 1);
+ //sleep(3);
+ igpio = getInt(CMD_SET_WTH_POWER);
+ igpio = getInt(CMD_SET_PULL_POWER);
+ igpio = getInt(CMD_SET_ANGLE_POWER);
+ igpio = getInt(CMD_SET_OTHER_POWER);
+ igpio = getInt(CMD_SET_PIC1_POWER);
+
+#endif
+#if 1
+ setInt(CMD_SET_SPI_POWER, 1);
+ setInt(CMD_SET_485_en0, 1);
+ setInt(CMD_SET_485_en1, 1);
+ setInt(CMD_SET_485_en2, 1);
+ setInt(CMD_SET_485_en3, 1);
+ setInt(CMD_SET_485_en4, 1);
+
+ //sleep(3);
+ igpio = getInt(CMD_SET_SPI_POWER);
+ igpio = getInt(CMD_SET_485_en0);
+ igpio = getInt(CMD_SET_485_en1);
+ igpio = getInt(CMD_SET_485_en2);
+ igpio = getInt(CMD_SET_485_en3);
+ igpio = getInt(CMD_SET_485_en4);
+
+#else
+ setInt(CMD_SET_485_en0, 0);
+ setInt(CMD_SET_485_en1, 0);
+ setInt(CMD_SET_485_en2, 0);
+ setInt(CMD_SET_485_en3, 0);
+ setInt(CMD_SET_485_en4, 0);
+#endif
+
+ /* 打开电源*/
+ //switch(port)
+
+}
+
+// 查询传感器电源状态
+char Gm_GetSensorsPowerState(int port)
+{
+ char iIoNo, cstate=0;
+ //char szbuf[128];
+
+ /* 查询电源状态*/
+ //switch(port)
+
+
+ return cstate;
+}
+
+void BytestreamLOG(int commid, char* describe, u_char* buf, int len, char flag)
+{
+ int i;
+ char szbuf[4096];
+
+ memset(szbuf, 0, sizeof(szbuf));
+ if(NULL != describe)
+ strncpy(szbuf, describe, strlen(describe));
+ for (i = 0; i < len; i++)
+ {
+ sprintf(szbuf, "%s %02X", szbuf, buf[i]);
+ }
+ SaveLogTofile(commid, szbuf);
+ switch (flag)
+ {
+ case 'E':
+ LOGE("%s", szbuf);
+ break;
+ case 'I':
+ LOGI("%s", szbuf);
+ break;
+ case 'D':
+ LOGD("%s", szbuf);
+ break;
+ case 'V':
+ LOGV("%s", szbuf);
+ break;
+ case 'W':
+ LOGW("%s", szbuf);
+ break;
+ default:
+ LOGI("%s", szbuf);
+ break;
+ }
+}
+
+// 打开串口通讯
+void Gm_OpenSerialPort(int devidx)
+{
+ int fd = -1;
+ char szbuf[512];
+
+ if((devidx < 0) || (devidx >= MAX_SERIAL_DEV_NUM))
+ return;
+ memset(szbuf, 0, sizeof(szbuf));
+ if(serialport[devparam[devidx].commid].fd <= 0)
+ {
+ fd = open(devparam[devidx].pathname, O_RDWR | O_NDELAY);
+ if(fd < 0)
+ {
+ sprintf(szbuf, "装置%d 打开串口%d %s失败!fd=%d", devidx+1, devparam[devidx].pathname, devparam[devidx].commid+1, fd);
+ DebugLog(devparam[devidx].commid, szbuf, 'E');
+ return;
+ }
+ sprintf(szbuf, "装置%d 打开串口%d %s成功!fd=%d", devidx+1, devparam[devidx].commid+1, devparam[devidx].pathname, fd );
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ serialport[devparam[devidx].commid].fd = fd;
+ return;
+ }
+ sprintf(szbuf, "装置%d 串口%d %s已经打开!fd=%d", devidx+1, devparam[devidx].commid+1, devparam[devidx].pathname,serialport[devparam[devidx].commid].fd);
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+}
+
+// 关闭串口通讯
+void Gm_CloseSerialPort()
+{
+ int i;
+
+ for(i=0; i 0)
+ {
+ close(serialport[i].fd);
+ serialport[i].fd = -1;
+ }
+ }
+
+}
+
+/*******************************************************************************
+函数名称: int GM_SerialComSend(const BYTE * cSendBuf, DWORD nSendLen, int commid)
+功能说明:串口发送数据 返回实际发送的字节数
+输入参数:
+输出参数:
+其它说明:
+*********************************************************************************/
+int GM_SerialComSend(unsigned char * cSendBuf, LONG nSendLen, int commid)
+{
+ int i, len;
+ char szbuf[512];
+
+ memset(szbuf, 0, sizeof(szbuf));
+ len = write(serialport[commid].fd, cSendBuf, (size_t)nSendLen);/* 向串囗发送字符串 */
+ //serialport[commid].RevCmdFlag = 0;
+ //LOGE("发送命令时间差%ld毫秒", get_msec() - isendtime);
+ //isendtime = time(NULL);
+ //isendtime = get_msec();
+ if (len < 0)
+ {
+ sprintf(szbuf, "write data error ");
+ DebugLog(commid, szbuf, 'E');
+ return -1;
+ }
+ else if(len > 0)
+ {
+ ;
+ }
+ return len;
+}
+
+int Gm_SetSerialPortParam(int commid)
+{
+ int ret;
+ char szbuf[128];
+ SERIAL_PARAM *pPortParam=NULL;
+
+ pPortParam = &devparam[srdt.curdevidx[commid]];
+ ret= set_port_attr (serialport[commid].fd, pPortParam->baudrate,pPortParam->databit,pPortParam->stopbit,pPortParam->parity,0,0 );/*9600 8n1 */
+ if(ret < 0)
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf,"串口%d 波特率等参数设置错误!", commid+1);
+ DebugLog(commid, szbuf, 'E');
+ return -1;
+ }
+ return ret;
+}
+
+void Gm_InitSerialComm_Test()
+{
+ int i, j;
+ SENSOR_PARAM sensorParam[MAX_SERIAL_DEV_NUM];
+
+#if 0
+ srdt.PtzCmdType = Cmd_Cancel; // 云台指令类型
+ for(i=0; i*/
+ //sprintf(devparam[i].pathname, "/dev/swk3");
+ devparam[i].commid = 0;
+ break;
+ case SLANT_PROTOCOL:
+ //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
+ /* 目前还不确定具体串口分配,暂时默认使用串口1*/
+ //sprintf(devparam[i].pathname, "/dev/swk2");
+ devparam[i].commid = 2;
+ break;
+ case RALLY_PROTOCOL:
+ //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
+ /* 目前还不确定具体串口分配,暂时默认使用串口1*/
+ //sprintf(devparam[i].pathname, "/dev/swk1");
+ devparam[i].commid = 1;
+ break;
+ case PELCO_D_PROTOCOL: /* 摄像机协议*/
+ case PELCO_P_PROTOCOL: /* 摄像机协议*/
+ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/
+ //memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
+ /* 目前还不确定//具体串口分配,暂时默认使用串口1*/
+ //sprintf(devparam[i].pathname, "/dev/ttyS1");
+ devparam[i].commid = 1;
+ srdt.camerauseserial = 1;
+ break;
+ default:
+ devparam[i].IsNoInsta = 0;
+ break;
+ }
+ }
+}
+
+void GM_StartSerialComm()
+{
+ int i, j, commid;
+ char szbuf[64], logbuf[128];
+ //LONG polltime=0;
+
+ // 此处不能对轮询设备标识清零,否则如果先起摄像机,就会导致poll乱掉
+ //memset((void*)srdt.curdevidx, 0, sizeof(srdt.curdevidx));
+ //Gm_OpenSerialPower(); /* 不在这使用*/
+ //FindDevUseSerialCommNo();
+ // 初始化串口使用状态(需要考虑不同时间启用了摄像机使用)
+ for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
+ {
+ if(i == srdt.camerauseserial)
+ continue;
+ serialport[i].Retry = 0;
+ serialport[i].RetryTime = 800;
+ serialport[i].WaitTime = 20;
+ serialport[i].m_iRevStatus = 0;
+ serialport[i].m_iRecvLen = 0;
+ serialport[i].m_iNeedRevLength = 0;
+ serialport[i].fd = -1;
+ memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区
+ ClearCmdFormPollCmdBuf(i);
+ }
+#if 0/* 简化插入使用摄像机过程,摄像机使用单独的串口*/
+ else
+ {
+ for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
+ {
+ for(j=0; j= MAX_SERIAL_PORT_NUM))
+ return;
+ serialport[i].Retry = 0;
+ serialport[i].RetryTime = 1000;
+ serialport[i].WaitTime = 0;
+ serialport[i].m_iRevStatus = 0;
+ serialport[i].m_iRecvLen = 0;
+ serialport[i].m_iNeedRevLength = 0;
+ serialport[i].fd = -1;
+ memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区
+ ClearCmdFormPollCmdBuf(i);
+
+ // 初始化串口使用状态
+ for(i=0; idevparam[i].CameraChannel) || (devparam[i].CameraChannel >MAX_CHANNEL_NUM))
+ {
+ srdt.ms_dev[i].IsNeedSerial = 0;
+ break;
+ }
+ if(channel == devparam[i].CameraChannel)
+ {
+ ;
+ }
+ else
+ break;
+ if(0 == srdt.ms_dev[i].IsNeedSerial)
+ srdt.iLastGetPhotoNo = -1;
+ else
+ srdt.iLastGetPhotoNo = srdt.ms_dev[i].SerialCmdidx;
+ srdt.ms_dev[i].IsNeedSerial = 1;
+ if(0 == cmdidx)
+ srdt.ms_dev[i].image.state = StartSample;
+ if((0 == cmdidx) && (srdt.presetno > 0 ))
+ {
+ srdt.ms_dev[i].SerialCmdidx = 10017;
+ srdt.iLastGetPhotoNo = cmdidx;
+ }
+ else
+ srdt.ms_dev[i].SerialCmdidx = cmdidx;
+ srdt.ms_dev[i].FirstCmdTimeCnt = get_msec();
+ srdt.sendphotocmdcnt = 0;
+ sprintf(szbuf, "摄像机");
+ flag = 1;
+ break;
+ default:
+ if(1 == srdt.ms_dev[i].IsNeedSerial)
+ break;
+ srdt.ms_dev[i].IsNeedSerial = 0;
+ break;
+ }
+ if(1 == srdt.ms_dev[i].IsNeedSerial)
+ {
+ sprintf(logbuf, "装置%d, IsNoInsta=%d, 类型:%s", i+1, devparam[i].IsNoInsta, szbuf);
+ DebugLog(8, logbuf, 'I');
+ Gm_OpenSensorsPower();
+ Gm_OpenSerialPort(i);
+ }
+ }
+ if(0x01 == flag)
+ {
+ sprintf(szbuf, "摄像机启动串口定时器!");
+ DebugLog(8, szbuf, 'I');
+ for(;;)
+ {
+ usleep(10);
+ //LOGW("polltime=%ldms", get_msec()-polltime);
+ //polltime = get_msec();
+ if(GM_SerialTimer() < 0)
+ {
+ //LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
+ DebugLog(8, "退出拍照流程!", 'V');
+ sleep(3);
+ break;
+ }
+ }
+ }
+ //return;
+}
+#endif
+
+int GM_SerialTimer(void)
+{
+ int flag = -1;
+
+ GM_AllSerialComRecv();
+ GM_IsCloseSensors();
+ Gm_FindAllSensorsCommand();
+ GM_AllSerialComRecv();
+ flag = GM_CloseTimer();
+ return flag;
+}
+
+/********************************************************************************
+函数名称: void Gm_FindAllSensorsCommand()
+功能说明:轮询所有串口和传感器是否需要生成下发命令
+输入参数:
+输出参数:
+其它说明:
+*********************************************************************************/
+void Gm_FindAllSensorsCommand()
+{
+ int i, j,curidx,flag;
+
+ //Gm_CheckSensorsPower(); /* 暂时不考虑电源控制*/
+ for(j=0; j 0)
+ break;
+ //LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
+ //LOGE("3.3V state= %d", getInt(CMD_SET_CAM_3V3_EN_STATE));
+ //LOGE("485 state=%d", getInt(CMD_SET_485_EN_STATE));
+
+
+ flag = -1;
+ switch(devparam[curidx].ProtocolIdx)
+ {
+ case WEATHER_PROTOCOL: /* 温湿度气压*/
+ case RALLY_PROTOCOL: /* 拉力*/
+ case WIND_PROTOCOL: /* 风速风向*/
+ case SLANT_PROTOCOL: /* 倾角*/
+ flag = FindNextShxyProtocolCommand(curidx);
+ break;
+ case RESERVE2_PROTOCOL:
+ break;
+ case RESERVE5_PROTOCOL:
+ break;
+ case PELCO_D_PROTOCOL: /* 摄像机协议*/
+ case PELCO_P_PROTOCOL: /* 摄像机协议*/
+ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/
+ flag = FindNextCameraPhotoCommand(curidx);
+ break;
+ break;
+ }
+ if(flag == -1)
+ continue;
+ srdt.curdevidx[j] = curidx;
+ break;
+ }
+ // 发送缓冲区中命令 生成了命令之后紧接着进行命令发送
+ SendCmdFormPollCmdBuf(j);
+ }
+}
+
+/********************************************************************************
+函数名称: void GM_IsCloseSensors()
+功能说明:检查所有传感器是否采集完毕,采集完毕的关闭传感器电源
+输入参数:
+输出参数:
+其它说明:
+*********************************************************************************/
+void GM_IsCloseSensors()
+{
+ int i, j;
+ char buf[256];
+ LONG lctime;
+
+ lctime = get_msec();
+ for(i=0; i 50*1000) ||(lctime-srdt.ms_dev[i].FirstCmdTimeCnt < 0))
+ {
+ srdt.ms_dev[i].FirstCmdTimeCnt = lctime;
+ break;
+ }
+ if(lctime - srdt.ms_dev[i].FirstCmdTimeCnt > 15*1000)
+ {
+ srdt.ms_dev[i].IsNeedSerial = 0;
+ // 关闭传感器电源
+ sprintf(buf, "读取装置%d数据%0.3f秒,关闭装置%d电源!", i+1, (get_msec()-srdt.ms_dev[i].FirstCmdTimeCnt)/1000.0,i+1);
+ DebugLog(devparam[i].commid, buf, 'I');
+ for(j=0;jdevparam[i].ProtocolIdx)))
+ break;
+ }
+ if(i < MAX_SERIAL_DEV_NUM)
+ {
+ return 1; // 寻找
+ }
+ else // 关闭所有串口及电源
+ {
+ Gm_CloseSerialPort();
+ for(j=0; j< MAX_SERIAL_DEV_NUM; j++)
+ Gm_CloseSensorsPower();
+ for(j=0; jimage.imagelen);
+ if(NULL == image)
+ return -1;
+ tempphoto = image;
+ for (i = 0; i < pPortParam->image.imagenum; ++i) {
+ memmove(tempphoto, &pPortParam->image.buf[i], (size_t)pPortParam->image.ilen[i]);
+ tempphoto += (size_t)pPortParam->image.ilen[i];
+ }
+
+ memset(szbuf, 0, sizeof(szbuf));
+ //memset(filedir, 0, sizeof(filedir));
+ //sprintf(filedir, "/sdcard/photo/");
+
+ if(access(srdt.filedir, 0)==0)
+ {
+ sprintf(szbuf,"文件路径%s已经存在!", srdt.filedir);
+ DebugLog(devparam[devno].commid, szbuf, 'I');
+ }
+ else
+ {
+ status = mkdir(srdt.filedir, S_IRWXU | S_IRWXG | S_IRWXO);
+ if(status < 0)
+ return -1;
+ }
+ // 写入文件到sdcard
+ memset(pPortParam->image.photoname, 0, sizeof(pPortParam->image.photoname));
+ sprintf(pPortParam->image.photoname, "%s%d-%d-%d.jpg", srdt.filedir,devparam[devno].CameraChannel, pPortParam->image.presetno, pPortParam->image.phototime);
+ fp = fopen(pPortParam->image.photoname, "wb+");
+ if(NULL == fp)
+ return -1;
+ len = fwrite(image,1, pPortParam->image.imagelen, fp);
+ fclose(fp);
+ free(image);
+ image = NULL;
+ if(len < pPortParam->image.imagelen)
+ return -1;
+ else
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf,"写入图片文件%s成功!", pPortParam->image.photoname);
+ DebugLog(devparam[devno].commid, szbuf, 'I');
+ return 1;
+ }
+}
+
+/*******************************************************************
+* 读 摄像机 数据 *
+*******************************************************************/
+void CameraRecvData(int devno, u_char *buf, int len)
+{
+ int i;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ if((devno<0) || (devno > MAX_SERIAL_DEV_NUM))
+ {
+ return;
+ }
+ pPortParam = &serialport[devparam[devno].commid];
+
+ for(i=0; im_iRevStatus)
+ {
+ case 0: // 0x68
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 1: // len1
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ break;
+ case 2: // len2
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ pPortParam->m_iNeedRevLength = pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2]*256+buf[i]+5;
+ break;
+ case 3: // 0x68
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iNeedRevLength--;
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 4: // 正确接收数据
+ pPortParam->m_iNeedRevLength--;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iNeedRevLength > 0)
+ break;
+ if(buf[i] != 0x16)
+ {
+ pPortParam->m_iRevStatus=18;
+ break;
+ }
+
+ if(pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2] ==
+ CalLpc( &pPortParam->m_au8RecvBuf[4], pPortParam->m_iRecvLen-6 ))
+ {
+ CameraPhotoPortDataProcess(devno);
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->RevCmdFlag = 1;
+ }
+ else
+ {
+ pPortParam->m_iRevStatus = 0;
+ }
+ pPortParam->m_iRecvLen = 0;
+ break;
+ case 255:// 错误接收数据
+ default:
+ if(buf[i] == 0x68)
+ {
+ pPortParam->m_iRevStatus = 1;
+ pPortParam->m_iRecvLen = 1;
+ pPortParam->m_au8RecvBuf[0] = buf[i];
+ }
+ else if(buf[i] == 0x16)
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->m_iRecvLen = 0;
+ }
+ else
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iRecvLen > 200)
+ {
+ pPortParam->m_iRecvLen = 0;
+ }
+ }
+ break;
+ }
+ }
+}
+
+/*********************************************************************************
+ CameraPhoto 端口数据处理
+**********************************************************************************/
+void CameraPhotoPortDataProcess( int devno)
+{
+ RTUMSG rtumsg;
+ SERIAL_DEV_DEF *pPortParam;
+ SIO_PARAM_SERIAL_DEF *curserial;
+ int img_file_size, packetnum, iNo, packsize, i=0, presetno, iphototime, pidx;
+ char szbuf[128];
+ WORD uDevAddr;
+ BYTE cmdidx, recvend;
+
+ pPortParam = &srdt.ms_dev[devno];
+ curserial = &serialport[devparam[devno].commid];
+
+ memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData));
+ memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen);
+ rtumsg.MsgLen = curserial->m_iRecvLen;
+ rtumsg.PortIdx = devparam[devno].commid;
+ cmdidx = curserial->m_au8RecvBuf[5];
+ uDevAddr = curserial->m_au8RecvBuf[4];
+
+ //sprintf(szbuf, "摄像机地址%d,命令%02X!", uDevAddr, cmdidx);
+ //DebugStringPrintf(szbuf, strlen(szbuf), 1);
+ if(uDevAddr != devparam[devno].devaddr)
+ return;
+ memset(szbuf, 0, sizeof(szbuf));
+ switch(cmdidx)
+ {
+ case 0x10: /* 拍照应答*/
+ if(0xFF == rtumsg.MsgData[6])
+ {
+ srdt.RephotographCnt++;
+ if(srdt.RephotographCnt > 2)
+ {
+ pPortParam->SerialCmdidx = -1;
+ sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!",srdt.RephotographCnt);
+ DebugLog(devparam[devno].commid, szbuf, 'E');
+ }
+ break;
+ }
+ i = 6;
+ memset(&pPortParam->image, 0, sizeof(pPortParam->image));
+ iphototime = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24);
+ srdt.photographtime = iphototime;
+ pPortParam->image.phototime = iphototime;
+ i=10;
+ img_file_size = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24);
+ packetnum = rtumsg.MsgData[i+5]+(rtumsg.MsgData[i+4]<<8);
+ pPortParam->image.imagelen = img_file_size;
+ pPortParam->image.imagenum = packetnum;
+ srdt.imagepacketnum = packetnum;
+ srdt.historyimagenum[devparam[devno].CameraChannel-1] = rtumsg.MsgData[i+7]+(rtumsg.MsgData[i+6]<<8);
+ sprintf(szbuf, "有%d张历史图片!",srdt.historyimagenum[devparam[devno].CameraChannel-1]);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ presetno = (int)rtumsg.MsgData[i+8];
+ pPortParam->image.presetno = presetno;
+ pPortParam->image.state = Sample;
+ curserial->RevCmdFlag = 1;
+ pPortParam->SerialCmdidx = 1;
+ srdt.sendphotocmdcnt = 0;
+ break;
+ case 0x11: /* 图片数据包*/
+ i = 6;
+ iNo = rtumsg.MsgData[i+1]+rtumsg.MsgData[i]*256;
+ packsize = rtumsg.MsgData[i+3]+rtumsg.MsgData[i+2]*256;
+ memmove(&pPortParam->image.buf[iNo-1], &rtumsg.MsgData[i+4], packsize);
+ pPortParam->image.ilen[iNo-1] = packsize;
+ sprintf(szbuf, "收到第%d(总%d包)包长=%d", iNo, srdt.imagepacketnum, packsize);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ curserial->RevCmdFlag = 1;
+ pPortParam->FirstCmdTimeCnt = get_msec();
+ if((iNo == pPortParam->SerialCmdidx) && (0xFF > rtumsg.MsgData[i+2]))
+ {
+ if(iNo == srdt.imagepacketnum)
+ { /* 检查是否有漏包*/
+ for(pidx = 0; pidx < srdt.imagepacketnum; pidx++)
+ {
+ if(pPortParam->image.ilen[pidx] < 1)
+ break;
+ }
+ if(pidx < srdt.imagepacketnum)
+ {
+ iNo = pidx;
+ recvend = 0;
+ }
+ else
+ {
+ if((1 == SaveImageDataTofile(devno)) && (Sample == pPortParam->image.state))
+ pPortParam->image.state = PHOTO_SAVE_SUCC;
+ recvend = 1;
+ }
+ }
+ else
+ recvend = 0;
+
+ if(packsize > MAX_PHOTO_FRAME_LEN)
+ recvend = 0xFF;
+
+ if(1 == recvend)
+ {
+ pPortParam->SerialCmdidx = 10002;/* 图片读取完成*/
+ //pPortParam->image.lastlen = packsize;
+ }
+ else if(0xFF == recvend)
+ {
+ pPortParam->SerialCmdidx = -1;
+ }
+ else
+ {
+ if((iNo > srdt.imagepacketnum) || (0 >= srdt.imagepacketnum))
+ {
+ pPortParam->SerialCmdidx = -1;
+ }
+ else
+ pPortParam->SerialCmdidx = iNo+1;
+ }
+ srdt.errorPhotoNoCnt = 0;
+ break;
+ }
+ srdt.errorPhotoNoCnt++;
+ sprintf(szbuf, "问询第%d包图片摄像机应答第%d包,连续错误%d次!",
+ pPortParam->SerialCmdidx, iNo, srdt.errorPhotoNoCnt);
+ DebugLog(devparam[devno].commid, szbuf, 'E');
+ if(srdt.errorPhotoNoCnt > 5)
+ {
+ pPortParam->SerialCmdidx = 0;
+ srdt.RephotographCnt++;
+ if(srdt.RephotographCnt > 2)
+ {
+ pPortParam->SerialCmdidx = -1;
+ sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!",srdt.RephotographCnt);
+ DebugLog(devparam[devno].commid, szbuf, 'E');
+ }
+ }
+ break;
+ case 0x03:
+ sprintf(szbuf, "设置波特率%d成功", devparam[devno].baudrate);
+ DebugLog(devparam[devno].commid, szbuf, 'D');
+ pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ curserial->RevCmdFlag = 1;
+ pPortParam->FirstCmdTimeCnt = get_msec();
+ break;
+ case 0x15:
+ if(0xFF == rtumsg.MsgData[6])
+ {
+ pPortParam->SerialCmdidx = -1;
+ sprintf(szbuf, "没有历史图片!结束读取图片!");
+ DebugLog(devparam[devno].commid, szbuf, 'I');
+ break;
+ }
+ i = 6;
+ iphototime = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24);
+ srdt.photographtime = iphototime;
+ pPortParam->image.phototime = iphototime;
+ i=10;
+ img_file_size = rtumsg.MsgData[i+3]+ (rtumsg.MsgData[i+2]<<8)+(rtumsg.MsgData[i+1]<<16)+(rtumsg.MsgData[i]<<24);
+ packetnum = rtumsg.MsgData[i+5]+(rtumsg.MsgData[i+4]<<8);
+ pPortParam->image.imagelen = img_file_size;
+ pPortParam->image.imagenum = packetnum;
+ srdt.imagepacketnum = packetnum;
+ srdt.historyimagenum[devparam[devno].CameraChannel-1] = rtumsg.MsgData[i+7]+(rtumsg.MsgData[i+6]<<8);
+ presetno = rtumsg.MsgData[i+8];
+ pPortParam->image.presetno = presetno;
+ sprintf(szbuf, "读取历史图片,还有%d张历史图片!",srdt.historyimagenum[devparam[devno].CameraChannel-1]);
+ DebugLog(devparam[devno].commid, szbuf, 'I');
+ curserial->RevCmdFlag = 1;
+ pPortParam->SerialCmdidx = 1;
+ srdt.sendphotocmdcnt = 0;
+ break;
+ case 0x16:
+ if(0xFF == rtumsg.MsgData[10])
+ {
+ pPortParam->SerialCmdidx = -1;
+ sprintf(szbuf, "摄像机图片保存失败!");
+ DebugLog(devparam[devno].commid, szbuf, 'E');
+ }
+ pPortParam->SerialCmdidx = -1;
+ if(0 == rtumsg.MsgData[10])
+ {
+ if(0 == srdt.historyimagenum[devparam[devno].CameraChannel-1])
+ {
+ ;
+ }
+ else
+ {
+ pPortParam->SerialCmdidx = 10003;/* 暂时不实现*/
+ }
+ }
+ pPortParam->FirstCmdTimeCnt = get_msec();
+ curserial->RevCmdFlag = 1;
+ break;
+ default:
+ curserial->RevCmdFlag = 1;
+ break;
+ }
+}
+
+/*********************************************************************************
+ 发送命令
+**********************************************************************************/
+void SendCmdFormPollCmdBuf( int port )
+{
+ char buf[128];
+ int len, ret;
+ LONG lctime;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ pPortParam = &serialport[port];
+ memset(buf, 0, sizeof(buf));
+ lctime = get_msec();
+ if(pPortParam->ForceWaitFlag && pPortParam->ForceWaitCnt)
+ {
+ pPortParam->ForceWaitCnt--;
+ return;
+ }
+
+ if(pPortParam->SendCmdFlag && (pPortParam->RevCmdFlag == 0))
+ {
+ //pPortParam->RetryTimeCnt++;
+ if((lctime - pPortParam->RetryTimeCnt > 3*pPortParam->RetryTime) || (lctime - pPortParam->RetryTimeCnt < 0))
+ {
+ pPortParam->RetryTimeCnt = lctime;
+ return;
+ }
+ if(lctime - pPortParam->RetryTimeCnt < pPortParam->RetryTime)
+ //if(pPortParam->RetryTimeCnt < pPortParam->RetryTime)
+ {
+ return;
+ }
+ pPortParam->RetryTimeCnt = lctime;
+ pPortParam->RetryCnt++;
+ if(pPortParam->RetryCnt > pPortParam->Retry)
+ {
+ ClearCmdFormPollCmdBuf(port);
+ }
+ else
+ {
+ pPortParam->SendCmdFlag = 0;
+ pPortParam->RevCmdFlag = 0;
+ pPortParam->ReSendCmdFlag = 1;
+ }
+ }
+
+ if ( pPortParam->SendCmdFlag && pPortParam->RevCmdFlag )
+ {
+ // 清除当前命令
+ ClearCmdFormPollCmdBuf(port);
+ }
+
+ if(pPortParam->WaitTime > 0)
+ {
+ if((lctime - pPortParam->WaitTimeCnt > 30*pPortParam->WaitTime) || (lctime - pPortParam->WaitTimeCnt < 0))
+ {
+ pPortParam->WaitTimeCnt = lctime;
+ return;
+ }
+
+ if(lctime- pPortParam->WaitTimeCnt < pPortParam->WaitTime)
+ {
+ return;
+ }
+ }
+ pPortParam->WaitTimeCnt = lctime;
+
+ if ( pPortParam->ReSendCmdFlag )
+ len = pPortParam->cmdlen;
+ else
+ {
+ len = pPortParam->cmdlen;
+ pPortParam->RetryCnt = 0;
+ }
+ if ( len == 0 )
+ return;
+
+ serialport[devparam[srdt.curdevidx[port]].commid].m_iRecvLen = 0; // 当发送一条新指令时,清除接收状态
+ serialport[devparam[srdt.curdevidx[port]].commid].m_iRevStatus = 0;
+ if(serialport[port].fd < 0)
+ return;
+ ret = Gm_SetSerialPortParam(port);
+ if(ret < 0)
+ return;
+ len = GM_SerialComSend(&pPortParam->PollCmd[2], pPortParam->cmdlen-2, port);
+ if(len < 1)
+ {
+ sprintf(buf, "串口%d, 发送命令失败!", port+1);
+ DebugLog(port, buf, 'E');
+ }
+ else
+ {
+
+ sprintf(buf, "发送串口%d 装置%d命令:", port+1, srdt.curdevidx[port]+1);
+ BytestreamLOG(port, buf, &pPortParam->PollCmd[2], len, 'D');
+ sprintf(buf, "sendtimeconst= %lld", lctime-pPortParam->lsendtime);
+ DebugLog(port, buf, 'W');
+ pPortParam->lsendtime = lctime;
+ }
+ pPortParam->SendCmdFlag = 1;
+ pPortParam->ReSendCmdFlag = 0;
+ pPortParam->RevCmdFlag = 0;
+ pPortParam->RetryTimeCnt = lctime;
+
+ pPortParam->ForceWaitCnt = pPortParam->PollCmd[0]*256+pPortParam->PollCmd[1]+TIMER_CNT-1;
+ pPortParam->ForceWaitCnt /= TIMER_CNT;
+ if(pPortParam->ForceWaitCnt)
+ {
+ pPortParam->ForceWaitFlag = 1;
+ }
+}
+
+void ClearCmdAllFlag(int commid)
+{
+ if((commid < 0) || (commid >= MAX_SERIAL_PORT_NUM))
+ return;
+
+ serialport[commid].RetryCnt = 0;
+ serialport[commid].RetryTimeCnt = get_msec();
+ serialport[commid].WaitTimeCnt = get_msec();
+ serialport[commid].ForceWaitFlag = 0;
+ serialport[commid].ForceWaitCnt = 0;
+ serialport[commid].SendCmdFlag = 0;
+ serialport[commid].RevCmdFlag = 0;
+ serialport[commid].ReSendCmdFlag = 0;
+}
+
+void ClearCmdFormPollCmdBuf(int port)
+{
+ //int len, idx;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ if((port < 0) || (port >= MAX_SERIAL_PORT_NUM))
+ return;
+ pPortParam = &serialport[port];
+
+ pPortParam->cmdlen = 0;
+ memset(pPortParam->PollCmd, 0, sizeof(pPortParam->PollCmd));
+ srdt.serialstatus[port] = 0;
+ // 清除指令下发标识
+ ClearCmdAllFlag(port);
+}
+
+// 下发串口拍照指令控制
+int FindNextCameraPhotoCommand(int devidx)
+{
+ int imagesize=3, cmdno;
+ BYTE channel, imagequality=90, presetno;
+ WORD packetsize;
+ LONG lcurtime;
+ BYTE cmdidx=0x10;
+ char szbuf[128];
+
+ //如果命令缓冲区仍有命令,则退出本函数
+ if((devparam[devidx].commid+1 < 1) || (devparam[devidx].commid+1 > MAX_SERIAL_PORT_NUM))
+ return -1;
+ // if(serialport[devparam[devidx].commid].cmdlen > 0)
+ // return -1;
+ if(-1 == srdt.ms_dev[devidx].SerialCmdidx)/* 下发拍照指令*/
+ return -1;
+ channel = devparam[devidx].CameraChannel;
+ if((1>channel) || (channel >MAX_CHANNEL_NUM))
+ {
+ /* 通道号错误退出拍照流程*/;
+ srdt.ms_dev[devidx].SerialCmdidx = -1;
+ sprintf(szbuf, "装置配置中,通道号配置错误!结束拍照!");
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ }
+ cmdno = srdt.ms_dev[devidx].SerialCmdidx;
+ lcurtime = get_msec();
+ if((1 > cmdno) || (10000 <= cmdno)) {
+ if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 300)
+ return -1;
+ }
+ switch (cmdno)
+ {
+ case 0:/* 下发拍照指令*/
+ if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 3800)
+ return -1;
+ if((lcurtime-srdt.ms_dev[devidx].FirstCmdTimeCnt > 3*35*1000) ||(lcurtime-srdt.ms_dev[devidx].FirstCmdTimeCnt < 0))
+ {
+ srdt.ms_dev[devidx].FirstCmdTimeCnt = lcurtime;
+ return -1;
+ }
+
+ if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 35*1000)
+ {
+ srdt.ms_dev[devidx].SerialCmdidx = -1;
+ sprintf(szbuf, "串口摄像机未接或故障!结束拍照!");
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ return -1;
+ }
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "time=%lldms", lcurtime-srdt.ms_dev[devidx].FirstCmdTimeCnt);
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ packetsize = (WORD)MAX_PHOTO_FRAME_LEN;
+ srdt.sendphotocmdcnt++;
+ srdt.imagepacketnum = 0;
+ srdt.errorPhotoNoCnt = 0;
+ cmdidx = 0x10;
+ imagesize = srdt.bImageSize;
+ break;
+
+ case 10000: /* 下发设置串口波特率命令*/
+ switch(devparam[devidx].baudrate)
+ {
+ case B9600:
+ imagesize = 0x07;
+ break;
+ case B19200:
+ imagesize = 0x08;
+ break;
+ case B38400:
+ imagesize = 0x09;
+ break;
+ default:
+ sprintf(szbuf, "设置串口摄像机参数时,配置参数错误!退出设置!");
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return -1;
+ }
+
+ if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 15*1000)
+ {
+ srdt.ms_dev[devidx].SerialCmdidx = -1;
+ sprintf(szbuf, "设置串口摄像机参数时,15秒未收到摄像机应答!退出设置!");
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ return -1;
+ }
+ cmdidx = 0x03;
+ packetsize = 0xFFFF;
+ break;
+
+ case 10001: /* 通知摄像机图片读取完成或存储(16H)*/
+ case 10002:
+ cmdidx = 0x16;
+ if(10001 == cmdno)
+ packetsize = 1;
+ else
+ packetsize = 0;
+ imagesize = srdt.photographtime; /* 需要保存或删除的图片拍摄时间*/
+ break;
+
+ case 10003: /* 读取历史图片(15H)*/
+ cmdidx = 0x15;
+ packetsize = (WORD)MAX_PHOTO_FRAME_LEN;
+ break;
+
+ case 10005: /* 关闭功能*/
+ //Gm_CtrlPtzCmd(1, P_MOVE_LEFT);
+ //sleep(2);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ //sleep(20);
+ return 1;
+ case 10006: /* 自动扫描功能控制(1/0 打开/关闭该功能)*/
+ Gm_CtrlPtzCmd(channel, P_Auto_Scan);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10007: /* 光圈缩小(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_IRIS_CLOSE);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10008: /* 光圈放大(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_IRIS_OPEN);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10009: /* 近距离聚焦(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_FOCUS_NEAR);
+ usleep(100000);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10010: /* 远距离聚焦(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_FOCUS_FAR);
+ usleep(100000);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10011: /* 远离物体(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_ZOOM_WIDE);
+ usleep(100000);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10012: /* 接近物体(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_ZOOM_TELE);
+ usleep(100000);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10013: /* 向下移动镜头(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_MOVE_DOWN);
+ sleep(1);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10014: /* 向上移动镜头(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_MOVE_UP);
+ sleep(1);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10015: /* 向左移动镜头(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_MOVE_LEFT);
+ sleep(1);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10016: /* 向右移动镜头(1 有效)*/
+ Gm_CtrlPtzCmd(channel, P_MOVE_RIGHT);
+ sleep(1);
+ Gm_CtrlPtzCmd(channel, Cmd_Cancel);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ case 10017: /* 调用预置点*/
+ //srdt.presetno = 2;
+ Gm_CtrlPtzCmd(channel, MOVE_TO_PRESETNO+srdt.presetno);
+ sleep(2);
+ if(0 == srdt.IsSleep)
+ {
+ srdt.ms_dev[devidx].SerialCmdidx = 10017;
+ srdt.IsSleep++;
+ return 1;
+ }
+ //if(srdt.presetno > 1)
+ // srdt.presetno = 1;
+ // else
+ // srdt.presetno++;
+ //srdt.ms_dev[devidx].SerialCmdidx = -1;
+ //Gm_CtrlPtzCmd(channel, MOVE_TO_PRESETNO+srdt.presetno);
+ //usleep(1000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ srdt.IsSleep = 0;
+ return 1;
+ case 10018: /* 设置预置点*/
+ Gm_CtrlPtzCmd(channel, SET_PRESETNO+srdt.presetno);
+ usleep(100000);
+ srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
+ srdt.iLastGetPhotoNo = -1;
+ return 1;
+ default:
+ imagesize = 0xFF;
+ packetsize = (WORD)srdt.ms_dev[devidx].SerialCmdidx;
+ cmdidx = 0x11;
+#if 0
+ if(0 == srdt.IsSleep)
+ {
+ srdt.IsSleep++;
+ testComm();
+ }
+#endif
+ if(lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 35*1000)
+ {
+ srdt.ms_dev[devidx].SerialCmdidx = -1;
+ sprintf(szbuf, "读取第%d包图片数据35秒未收到!结束拍照!",packetsize);
+ DebugLog(devparam[devidx].commid, szbuf, 'I');
+ return -1;
+ }
+ break;
+ }
+ MakeCameraPhotoCommand(devidx, cmdidx, imagesize, packetsize, imagequality, srdt.sendphototime);
+ //MakeCameraPhotoCommand(devidx, 2, imagesize, packetsize, imagequality);
+ srdt.curdevidx[devparam[devidx].commid] = devidx;
+ return 1;
+}
+
+/*********************************************************************************
+ 生成 CameraPhoto命令
+**********************************************************************************/
+void MakeCameraPhotoCommand( int portno, BYTE cmdidx, int OneParam, WORD TwoParam, BYTE Threep, int phototime )
+{
+ int i, icurtime;
+ u_char *sendbuf;
+ //char szbuf[128];
+
+ sendbuf = serialport[devparam[portno].commid].PollCmd;
+
+ icurtime = phototime;
+ i = 0;
+ sendbuf[i++] = 0x00; /* 强制等待时间*/
+ sendbuf[i++] = 0x00; /* 强制等待时间*/
+ sendbuf[i++] = 0x68; /* 起始字符*/
+ sendbuf[i++] = (BYTE)0x00; /* length */
+ sendbuf[i++] = (BYTE)0x00; /* length */
+ sendbuf[i++] = 0x68; /* 起始字符*/
+ sendbuf[i++] = (BYTE)devparam[portno].devaddr;/* 传感器地址*/
+ sendbuf[i++] = cmdidx; /* 命令字*/
+ switch(cmdidx)
+ {
+ case 0x02: /* */
+ sendbuf[i-2] = 0xFF;
+ break;
+ case 0x03: /*设置传感器通讯参数(03H)*/
+ sendbuf[i++] = 0x00; /* 波特率*/
+ sendbuf[i++] = 0x00;
+ sendbuf[i++] = 0x00;
+ sendbuf[i++] = (BYTE)OneParam;
+ sendbuf[i++] = 0x08; /* 数据位*/
+ sendbuf[i++] = 0x00; /* 校验位*/
+ sendbuf[i++] = 0x01; /* 停止位*/
+ break;
+ case 0x010: /* 拍摄图片并指定大小分包(10H)*/
+ sendbuf[i++] = OneParam; /* 图片大小(Resolution)*/
+ sendbuf[i++] = HIBYTE(TwoParam);/*包大小(PackageSize)*/
+ sendbuf[i++] = LOBYTE(TwoParam);
+ sendbuf[i++] = HIBYTE(HIWORD(icurtime+8*60*60));/* 请求拍摄图片时间(PhotoTime)*/
+ sendbuf[i++] = LOBYTE(HIWORD(icurtime+8*60*60));
+ sendbuf[i++] = HIBYTE(LOWORD(icurtime+8*60*60));
+ sendbuf[i++] = LOBYTE(LOWORD(icurtime+8*60*60));
+ sendbuf[i++] = Threep;/*图像质量(ImageQuality)*/
+ sendbuf[i++] = srdt.presetno;//netportparam.CurPresetno[srdt.ms_dev[portno].CameraChannel-1];/*拍照预置点(PresetNo)*/
+ break;
+ case 0x11: /* 获取指定包数据(11H)*/
+ sendbuf[i++] = HIBYTE(TwoParam);/*图片包号:(PackageNo)*/
+ sendbuf[i++] = LOBYTE(TwoParam);
+ break;
+ case 0x15: /* 读取历史图片(15H)*/
+ sendbuf[i++] = HIBYTE(TwoParam);/*包大小(PackageSize)*/
+ sendbuf[i++] = LOBYTE(TwoParam);
+ break;
+ case 0x16: /* 通知摄像机图片读取完成或存储(16H)*/
+ sendbuf[i++] = HIBYTE(HIWORD(OneParam));/* 需要保存或删除的图片拍摄时间*/
+ sendbuf[i++] = LOBYTE(HIWORD(OneParam));
+ sendbuf[i++] = HIBYTE(LOWORD(OneParam));
+ sendbuf[i++] = LOBYTE(LOWORD(OneParam));
+ sendbuf[i++] = (BYTE)TwoParam; /* 是否需要保存*/
+ break;
+ }
+ sendbuf[i] = CalLpc((u_char *)&sendbuf[6],i-6);
+ i+= 1;
+ sendbuf[i++] = 0x16; /* 信息尾*/
+ sendbuf[3] = (BYTE)((i-10)>>8);
+ sendbuf[4] = (BYTE)(i-10);
+ serialport[devparam[portno].commid].cmdlen = i;
+ //return;
+}
+
+// 准备发送云台指令
+int Gm_CtrlPtzCmd(u_char channel, DWORD ptzcmd)
+{
+ int i;
+ char szbuf[64];
+
+ srdt.PtzCmdType = ptzcmd;
+ // 查找装置序号
+ for(i=0; i srdt.ms_dev[i].UseSerialidx+1) ||(MAX_SERIAL_PORT_NUM < srdt.ms_dev[i].UseSerialidx+1))
+ {
+ sprintf(szbuf, "通道%d摄像机错误的使用了串口%d", channel, srdt.ms_dev[i].UseSerialidx+1);
+ LOGI("%s", szbuf);
+ return 1;
+ }
+ else
+ {
+#endif
+ sprintf(szbuf, "摄像机通道%d 使用串口%d", channel, devparam[i].commid+1);
+ DebugLog(devparam[i].commid, szbuf, 'I');
+ //}
+ srdt.usecameradevidx = i;
+ // 查找串口序号
+ // 1.打开串口电源
+ //Gm_OpenSensorsPower();
+ // 2.打开串口通讯
+ //Gm_OpenSerialPort(i);
+
+ srdt.SendStopPtzCmdTimeCnt = -1;
+ //return 1;
+ return Gm_Camera_Timer();
+ //return 1;
+}
+
+// 发送转动摄像机云台命令定时器
+int Gm_Camera_Timer()
+{
+ char szbuf[128];
+
+ if(PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx)
+ {
+ switch(srdt.PtzCmdType)
+ {
+ case P_Auto_Scan:
+ srdt.PtzCmdType = D_Auto_Scan;
+ break;
+ case P_IRIS_CLOSE:
+ srdt.PtzCmdType = D_IRIS_CLOSE;
+ break;
+ case P_IRIS_OPEN:
+ srdt.PtzCmdType = D_IRIS_OPEN;
+ break;
+ case P_FOCUS_NEAR:
+ srdt.PtzCmdType = D_FOCUS_NEAR;
+ break;
+ case P_FOCUS_FAR:
+ srdt.PtzCmdType = D_FOCUS_FAR;
+ break;
+ case P_ZOOM_WIDE:
+ srdt.PtzCmdType = D_ZOOM_WIDE;
+ break;
+ case P_ZOOM_TELE:
+ srdt.PtzCmdType = D_ZOOM_TELE;
+ break;
+ case P_MOVE_DOWN:
+ srdt.PtzCmdType = D_MOVE_DOWN;
+ break;
+ case P_MOVE_UP:
+ srdt.PtzCmdType = D_MOVE_UP;
+ break;
+ case P_MOVE_LEFT:
+ srdt.PtzCmdType = D_MOVE_LEFT;
+ break;
+ case P_MOVE_RIGHT:
+ srdt.PtzCmdType = D_MOVE_RIGHT;
+ break;
+ }
+ }
+ if(srdt.SendStopPtzCmdTimeCnt == -1)
+ {
+ if(serialport[srdt.camerauseserial].cmdlen > 0)
+ return -1;
+ if(PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx)
+ Gm_SendPelco_DCommand(srdt.PtzCmdType);
+ else
+ Gm_SendPelco_pCommand(srdt.PtzCmdType);
+
+ if((SET_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000))
+ || (MOVE_TO_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000)))
+ {
+ //srdt.sampling &= 0xFD;
+ return 1;
+ }
+ srdt.PtzCmdType = Cmd_Cancel;
+ srdt.SendStopPtzCmdTimeCnt = 0;
+ }
+ return 1;
+#if 0
+ //if(srdt.SendStopPtzCmdTimeCnt > PTZ_MOVETIME*1000/TIMER_CNT)
+ {
+ if(serialport[srdt.camerauseserial].cmdlen > 0)
+ return -1;
+ if(PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx)
+ Gm_SendPelco_DCommand(srdt.PtzCmdType);
+ else
+ Gm_SendPelco_pCommand(srdt.PtzCmdType);
+ srdt.SendStopPtzCmdTimeCnt = -1;
+ //srdt.sampling &= 0xFD;
+ return 1;
+ }
+ //else
+ // srdt.SendStopPtzCmdTimeCnt ++;
+ //return -1;
+#endif
+}
+
+/********************************************************************************
+* 生成 PELCO_P 命令 *
+*********************************************************************************/
+void Gm_SendPelco_pCommand( DWORD cmdtype)
+{
+ int len;
+ BYTE commandbuf[32];
+ char buf[128];
+
+ len = 0;
+ commandbuf[len++] = (BYTE)0xA0;
+ commandbuf[len++] = (BYTE)devparam[srdt.usecameradevidx].devaddr;
+ commandbuf[len++] = (BYTE)(cmdtype>>24);
+ commandbuf[len++] = (BYTE)(cmdtype>>16);
+ commandbuf[len++] = (BYTE)(cmdtype>>8);
+ commandbuf[len++] = (BYTE)(cmdtype);
+ commandbuf[len++] = (BYTE)0xAF;
+ commandbuf[len] = (BYTE)Gm_Pelco_pXORCheck(commandbuf, len);
+ len++;
+ serialport[srdt.camerauseserial].cmdlen = len;
+ Gm_SetSerialPortParam(srdt.camerauseserial);
+ //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0ff,0x02,0x01,0x16};
+ //len = GM_SerialComSend(sendbuf, sizeof(sendbuf), srdt.camerauseserial);
+
+ len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial);
+ if(len < 1)
+ {
+ DebugLog(srdt.camerauseserial, "发送Pelco_p命令失败", 'E');
+ }
+ else
+ {
+ sprintf(buf, "发送串口%d 像机通道%d Pelco_P命令:",
+ srdt.camerauseserial+1, devparam[srdt.usecameradevidx].CameraChannel);
+ BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D');
+ }
+ ClearCmdFormPollCmdBuf(srdt.camerauseserial);
+}
+
+BYTE Gm_Pelco_pXORCheck( BYTE *msg, int len )
+{
+ int i;
+ BYTE checkvalue=0;
+
+ if(len <= 0)
+ return checkvalue;
+ checkvalue = msg[0];
+ for(i=1; i>24);
+ commandbuf[len++] = (BYTE)(cmdtype>>16);
+ commandbuf[len++] = (BYTE)(cmdtype>>8);
+ commandbuf[len++] = (BYTE)(cmdtype);
+ commandbuf[len] = (BYTE)Gm_Pelco_DCheck(commandbuf, len);
+#endif
+ len++;
+ serialport[srdt.camerauseserial].cmdlen = len;
+ Gm_SetSerialPortParam(srdt.camerauseserial);
+ len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial);
+ if(len < 1)
+ {
+ DebugLog(srdt.camerauseserial, "发送Pelco_D命令失败", 'E');
+ }
+ else
+ {
+ sprintf(buf, "发送串口%d 像机通道%d Pelco_D命令:",
+ srdt.camerauseserial+1, devparam[srdt.usecameradevidx].CameraChannel);
+ BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D');
+ }
+ ClearCmdFormPollCmdBuf(srdt.camerauseserial);
+ //serialport[srdt.camerauseserial].ForceWaitCnt = 10;
+ //serialport[srdt.camerauseserial].ForceWaitFlag = 1;
+}
+
+// 计算Pelco_D校验
+BYTE Gm_Pelco_DCheck( BYTE *msg, int len )
+{
+ int i;
+ BYTE checkvalue=0;
+
+ if(len <= 0)
+ return checkvalue;
+ checkvalue = 0;
+ for(i=1; i MAX_SERIAL_PORT_NUM))
+ return -1;
+ if(get_msec()-srdt.ms_dev[devidx].FirstCmdTimeCnt < 3*1000)
+ {
+ return -1;
+ }
+ //if(SLANT_PROTOCOL == devparam[devidx].ProtocolIdx)
+ // return -1;
+ switch (cmdno)
+ {
+ case 0: /* 正常采集数据*/
+ MakeShxyProtocolPollCommand(devidx, 0x09);
+ srdt.curdevidx[devparam[devidx].commid] = devidx;
+ return 1;
+ case 1: /* 测试读取地址*/
+ MakeShxyProtocolPollCommand(devidx, 0x02);
+ srdt.curdevidx[devparam[devidx].commid] = devidx;
+ return 1;
+ default:
+ break;
+ }
+ return -1;
+}
+
+/*********************************************************************************
+ 生成下发命令
+**********************************************************************************/
+void MakeShxyProtocolPollCommand(int portno, BYTE cmdidx)
+{
+ int i, length=0;
+ int newaddr = 9, baud = 9600, stopbit = 1, parity=0;
+ //char buf[128];
+ u_char *sendbuf;
+
+ sendbuf = serialport[devparam[portno].commid].PollCmd;
+
+ /* 测试变量*/
+ cmdidx =cmdidx;
+
+ i = 0;
+ sendbuf[i++] = 0x00; // 强制等待时间
+ sendbuf[i++] = 0x00; //
+ sendbuf[i++] = 0x68; // 起始字符
+ sendbuf[i++] = (BYTE)0x00; // length
+ sendbuf[i++] = (BYTE)0x00; // length
+ sendbuf[i++] = 0x68;
+ sendbuf[i++] = (BYTE)devparam[portno].devaddr; // 传感器地址
+ sendbuf[i++] = cmdidx; // 命令信息0x06
+ switch (cmdidx)
+ {
+ case 1: /* 设置传感器新地址*/
+ sendbuf[i++] = newaddr;
+ length = 1;
+ break;
+ case 2: /* 广播读地址*/
+ sendbuf[6] = 0xFF;
+ break;
+ case 3: /* 设置串口参数*/
+ sendbuf[i++] = (u_char)(baud >> 24);
+ sendbuf[i++] = (u_char)(baud >> 16);
+ sendbuf[i++] = (u_char)(baud >> 8);
+ sendbuf[i++] = (u_char)baud;
+ sendbuf[i++] = 8;
+ sendbuf[i++] = parity;
+ sendbuf[i++] = stopbit;
+ length = 7;
+ break;
+ default:
+ break;
+ }
+ sendbuf[i] = CalLpc((u_char *)&sendbuf[6],i-6);
+ i+= 1;
+ sendbuf[3] = length;
+ sendbuf[4] = length;
+ sendbuf[i++] = 0x16; // 信息尾
+ serialport[devparam[portno].commid].cmdlen = i;
+}
+
+unsigned char CalLpc(unsigned char *msg, int len)
+{
+ int i;
+ u_char retval = 0;
+
+ for (i = 0 ; i < len; i++)
+ retval += msg[i];
+ return retval;
+}
+
+/***************************************************************
+* 读上海欣影传感器协议数据 *
+***************************************************************/
+void ShxyProtocolRecvData(int devno, u_char *buf, int len)// 规约读数据处理
+{
+ int i, ictime;
+ //WORD crc, check;
+ //SERIAL_DEV_DEF *pPortParam;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ if((devno<0) || (devno > MAX_SERIAL_DEV_NUM))
+ {
+ return;
+ }
+ pPortParam = &serialport[devparam[devno].commid];
+
+ for(i=0; im_iRevStatus)
+ {
+ case 0: // 0x68
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 1: // len1
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ break;
+ case 2: // len2
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2])
+ {
+ pPortParam->m_iRevStatus++;
+ pPortParam->m_iNeedRevLength = buf[i]+5;
+ }
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 3: // 0x68
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iNeedRevLength--;
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 4: // 正确接收数据
+ pPortParam->m_iNeedRevLength--;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iNeedRevLength > 0)
+ break;
+ if(buf[i] != 0x16)
+ {
+ pPortParam->m_iRevStatus=18;
+ break;
+ }
+
+ if(CheckShxyProtocolLpcError(pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE)
+ {
+ ShxyProtocolDataProcess(devno);
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->RevCmdFlag = 1;
+ }
+ else
+ {
+ pPortParam->m_iRevStatus = 0;
+ }
+ pPortParam->m_iRecvLen = 0;
+ break;
+ case 255:// 错误接收数据
+ default:
+ if(buf[i] == 0x68)
+ {
+ pPortParam->m_iRevStatus = 1;
+ pPortParam->m_iRecvLen = 1;
+ pPortParam->m_au8RecvBuf[0] = buf[i];
+ }
+ else if(buf[i] == 0x16)
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->m_iRecvLen = 0;
+ }
+ else
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iRecvLen > 200)
+ {
+ pPortParam->m_iRecvLen = 0;
+ }
+ }
+ break;
+ }
+ }
+}
+
+//********************************************************************************
+// 检查检验和是否正确
+//********************************************************************************
+int CheckShxyProtocolLpcError( u_char* msg, int len )
+{
+ int bRetval = FALSE;
+ int iCheckLen;
+
+ if(0x68 == msg[0])
+ {
+ if ( msg[0] != msg[3] )
+ return bRetval;
+ if ( msg[len-1] != 0x16 )
+ return bRetval;
+ if ( msg[1] != msg[2] )
+ return bRetval;
+ iCheckLen = msg[1];
+ if ( CalLpc( &msg[4], iCheckLen+2 ) != msg[len-2] )
+ return bRetval;
+ bRetval = TRUE;
+ }
+ return bRetval;
+}
+
+/*********************************************************************************
+ 上海欣影传感器协议数据处理
+**********************************************************************************/
+void ShxyProtocolDataProcess( int devno)
+{
+ float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
+ WORD uDevAddr;
+ BYTE cmdidx;
+ int i, j, aipnt, datanum;
+ SERIAL_DEV_DEF *pPortParam;
+ SIO_PARAM_SERIAL_DEF *curserial;
+ char szbuf[64];
+
+ pPortParam = &srdt.ms_dev[devno];
+ curserial = &serialport[devparam[devno].commid];
+
+ //取出装置地址,开始处理地址+++
+ if(0x02 == curserial->m_au8RecvBuf[5])
+ {
+ devparam[devno].devaddr = curserial->m_au8RecvBuf[4];
+ return;
+ }
+
+ cmdidx = curserial->m_au8RecvBuf[5];
+ aipnt = pPortParam->SameTypeDevIdx;
+ uDevAddr = curserial->m_au8RecvBuf[4];
+
+ fvalua = &fvalue;
+ memset(szbuf, 0, sizeof(szbuf));
+ if(0x06 == cmdidx)
+ {
+ if(0x08 !=curserial->m_au8RecvBuf[1])
+ return;
+ pPortParam->recvdatacnt++;
+ if(pPortParam->recvdatacnt < 2)
+ return;
+ // ++++++++++++++++++++++++++++
+ //g_SelfTest.SensorsFault |= (0x800<m_au8RecvBuf[9];
+ *((BYTE*)fvalua+1) = curserial->m_au8RecvBuf[8];
+ *((BYTE*)fvalua+2) = curserial->m_au8RecvBuf[7];
+ *((BYTE*)fvalua+3) = curserial->m_au8RecvBuf[6];
+ if((fvalue < -59) ||(fvalue > 59))
+ {
+ frnb = (GeneratingRandomNumber()%101-50)/1000.0;
+ pPortParam->aiValue[0].EuValue *= (1+frnb);
+ }
+ else
+ pPortParam->aiValue[0].EuValue = fvalue;
+ pPortParam->aiValue[0].AiState = Sample;
+ //slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\
+ // +slantpntmsg[aipnt][0].AiParam.EuValueDelta;
+ //slantpntmsg[aipnt][0].AiState = 1;
+ //if ((gDisSunRain & 0x20) == 0x20)
+ {
+ sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f ", devparam[devno].devaddr, fvalue);
+ //DebugLog(devparam[devno].commid, szbuf, 'V');
+ }
+ //XslantSec[aipnt][srdt.SectimesamplingCnt[0]] = (short)slantpntmsg[aipnt][0].EuValue;
+ //srdt.SectimesamplingCnt[0] += 1;
+
+ *(BYTE*)fvalua = curserial->m_au8RecvBuf[13];
+ *((BYTE*)fvalua+1) = curserial->m_au8RecvBuf[12];
+ *((BYTE*)fvalua+2) = curserial->m_au8RecvBuf[11];
+ *((BYTE*)fvalua+3) = curserial->m_au8RecvBuf[10];
+ //if ((gDisSunRain & 0x20) == 0x20)
+ {
+ sprintf(szbuf, "%sY =%0.3f ", szbuf, fvalue);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ }
+ if((fvalue < -59) ||(fvalue > 59))
+ {
+ frnb = (GeneratingRandomNumber()%101-50)/1000.0;
+ pPortParam->aiValue[1].EuValue *= (1+frnb);
+ //slantpntmsg[aipnt][1].EuValue *= (1+frnb);
+ }
+ else
+ pPortParam->aiValue[1].EuValue = fvalue;
+ pPortParam->aiValue[1].AiState = Sample;
+ /*slantpntmsg[aipnt][1].EuValue = fvalue*slantpntmsg[aipnt][1].AiParam.fFactor\
+ +slantpntmsg[aipnt][1].AiParam.EuValueDelta;
+ slantpntmsg[aipnt][1].AiState = 1;*/
+ //YslantSec[aipnt][srdt.SectimesamplingCnt[1]] = (short)slantpntmsg[aipnt][1].EuValue;
+ srdt.SectimesamplingCnt[1] += 1;
+ }
+ datanum = curserial->m_au8RecvBuf[6];
+ if((0x08 != cmdidx) && (0x09 != cmdidx))
+ return;
+
+ for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 )
+ {
+ if(0x08 == cmdidx)
+ fvalue = (curserial->m_au8RecvBuf[j+1]<<24)+(curserial->m_au8RecvBuf[j+2]<<16)
+ +(curserial->m_au8RecvBuf[j+3]<<8)+curserial->m_au8RecvBuf[j+4];
+ else
+ {
+ *(BYTE*)fvalua = curserial->m_au8RecvBuf[j+4];
+ *((BYTE*)fvalua+1) = curserial->m_au8RecvBuf[j+3];
+ *((BYTE*)fvalua+2) = curserial->m_au8RecvBuf[j+2];
+ *((BYTE*)fvalua+3) = curserial->m_au8RecvBuf[j+1];
+ }
+ switch(curserial->m_au8RecvBuf[j])
+ {
+ case 1: /*温度*/
+ if((fvalue < -40) ||(fvalue > 85))
+ {
+ frnb = (GeneratingRandomNumber()%101-50)/1000.0;
+ pPortParam->aiValue[AirTempNo].EuValue *= (1+frnb);
+ weatherpntmsg[AirTempNo].EuValue *= (1+frnb);
+ //weatherpntmsg[AirTempNo].AiState = Sample;
+ }
+ else
+ {
+ pPortParam->aiValue[AirTempNo].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor + pPortParam->aiValue[0].AiParam.EuValueDelta;*/
+ weatherpntmsg[AirTempNo].EuValue = fvalue;/*weatherpntmsg[AirTempNo].AiParam.fFactor + weatherpntmsg[AirTempNo].AiParam.EuValueDelta;*/
+ }
+ pPortParam->aiValue[AirTempNo].AiState = Sample;
+ weatherpntmsg[AirTempNo].AiState = Sample;
+ //g_SelfTest.SensorsFault |= (0x01);
+ //if ((gDisSunRain & 0x80) == 0x80)
+ {
+ sprintf(szbuf, "ID:%d 温度:%0.3f ", devparam[devno].devaddr, fvalue);
+ //DebugLog(devparam[devno].commid, szbuf, 'V');
+ }
+ break;
+ case 2: /*气压*/
+ if((fvalue < 550) ||(fvalue > 1060))
+ {
+ frnb = (GeneratingRandomNumber()%41-20)/10000.0;
+ pPortParam->aiValue[AtmosNo].EuValue *= (1+frnb);
+ weatherpntmsg[AtmosNo].EuValue *= (1+frnb);
+ }
+ else
+ {
+ pPortParam->aiValue[AtmosNo].EuValue = fvalue;/*pPortParam->aiValue[5].AiParam.fFactor + pPortParam->aiValue[5].AiParam.EuValueDelta;*/
+ weatherpntmsg[AtmosNo].EuValue = fvalue;/*weatherpntmsg[AtmosNo].AiParam.fFactor + weatherpntmsg[AtmosNo].AiParam.EuValueDelta;*/
+ }
+ pPortParam->aiValue[AtmosNo].AiState = Sample;
+ weatherpntmsg[AtmosNo].AiState = Sample;
+ //g_SelfTest.SensorsFault |= (0x10);
+ //if ((gDisSunRain & 0x80) == 0x80)
+ {
+ sprintf(szbuf, "气压:%0.3f ", fvalue);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ }
+ break;
+ case 3: /*湿度*/
+ if((fvalue < 0) ||(fvalue > 100))
+ {
+ frnb = (GeneratingRandomNumber()%41-20)/1000.0;
+ pPortParam->aiValue[HumidityNo].EuValue *= (1+frnb);
+ weatherpntmsg[HumidityNo].EuValue *= (1+frnb);
+ }
+ else
+ {
+ pPortParam->aiValue[HumidityNo].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor + pPortParam->aiValue[1].AiParam.EuValueDelta;*/
+ weatherpntmsg[HumidityNo].EuValue = fvalue;/*weatherpntmsg[HumidityNo].AiParam.fFactor + weatherpntmsg[HumidityNo].AiParam.EuValueDelta;*/
+ }
+ pPortParam->aiValue[HumidityNo].AiState = Sample;
+ weatherpntmsg[HumidityNo].AiState = Sample;
+ //g_SelfTest.SensorsFault |= (0x02);
+ //if ((gDisSunRain & 0x80) == 0x80)
+ {
+ sprintf(szbuf, "%s湿度:%0.3f ", szbuf, fvalue);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ }
+ break;
+ case 4: /*雨量*/
+ break;
+ case 5: /*日照*/
+ break;
+ case 6: /*风速*/
+ if((fvalue < 0) ||(fvalue > 80))
+ {
+ frnb = (GeneratingRandomNumber()%41-20)/1000.0;
+ pPortParam->aiValue[WindSpeedNo].EuValue *= (1+frnb);
+ weatherpntmsg[WindSpeedNo].EuValue *= (1+frnb);
+ }
+ else
+ {
+ pPortParam->aiValue[WindSpeedNo].EuValue = fvalue;/*pPortParam->aiValue[2].AiParam.fFactor + pPortParam->aiValue[2].AiParam.EuValueDelta;*/
+ weatherpntmsg[WindSpeedNo].EuValue = fvalue;/*weatherpntmsg[WindSpeedNo].AiParam.fFactor + weatherpntmsg[WindSpeedNo].AiParam.EuValueDelta;*/
+ }
+ pPortParam->aiValue[WindSpeedNo].AiState = Sample;
+ weatherpntmsg[WindSpeedNo].AiState = Sample;
+ //g_SelfTest.SensorsFault |= (0x04);
+ //if ((gDisSunRain & 0x10) == 0x10)
+ {
+ //fwind = fvalue/1000*0.95;
+ //if(fvalue/1000 > 25)
+ // fwind -= 1.2;
+ //sprintf(szbuf, "风速:%0.3f ", fwind);
+ sprintf(szbuf, "ID:%d 风速:%0.3f ", devparam[devno].devaddr, fvalue);
+ }
+ break;
+ case 7: /*风向*/
+ if((fvalue/1000 < 0) ||(fvalue/1000 > 359.99))
+ {
+ frnb = (GeneratingRandomNumber()%41-20)/1000.0;
+ pPortParam->aiValue[WindDirectionNo].EuValue *= (1+frnb);
+ weatherpntmsg[WindDirectionNo].EuValue *= (1+frnb);
+ }
+ else
+ {
+ pPortParam->aiValue[WindDirectionNo].EuValue = fvalue;/*pPortParam->aiValue[3].AiParam.fFactor + pPortParam->aiValue[3].AiParam.EuValueDelta;*/
+ weatherpntmsg[WindDirectionNo].EuValue = fvalue;/*weatherpntmsg[WindDirectionNo].AiParam.fFactor + weatherpntmsg[WindDirectionNo].AiParam.EuValueDelta;*/
+ }
+ pPortParam->aiValue[WindDirectionNo].AiState = Sample;
+ weatherpntmsg[WindDirectionNo].AiState = Sample;
+ //g_SelfTest.SensorsFault |= (0x08);
+ //if ((gDisSunRain & 0x10) == 0x10)
+ {
+ sprintf(szbuf, "%s 风向:%0.3f ", szbuf, fvalue);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ }
+ break;
+ case 8: /*拉力*/
+ pPortParam->recvdatacnt++;
+ if(pPortParam->recvdatacnt < 2)
+ break;
+
+ pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\
+ +pPortParam->aiValue[0].AiParam.EuValueDelta;*/
+ //rallypntmsg[aipnt][0].EuValue = fvalue*rallypntmsg[aipnt][0].AiParam.fFactor\
+ // +rallypntmsg[aipnt][0].AiParam.EuValueDelta;
+ pPortParam->aiValue[0].AiState = Sample;
+ //rallypntmsg[aipnt][0].AiState = 1;
+ sprintf(szbuf, "地址%d拉力:%0.3fKg ", devparam[devno].devaddr, fvalue);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+ //}
+ break;
+ case 9: /*倾角传感器X轴倾角*/
+ if((fvalue < -59) ||(fvalue > 59))
+ {
+ frnb = (GeneratingRandomNumber()%101-50)/1000.0;
+ pPortParam->aiValue[0].EuValue *= (1+frnb);
+ //slantpntmsg[aipnt][0].EuValue *= (1+frnb);
+ }
+ else
+ {
+ pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\
+ +pPortParam->aiValue[0].AiParam.EuValueDelta;*/
+ //slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\
+ //+slantpntmsg[aipnt][0].AiParam.EuValueDelta;
+ }
+ pPortParam->aiValue[0].AiState = Sample;
+ //slantpntmsg[aipnt][0].AiState = 1;
+ sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f ", devparam[devno].devaddr, fvalue);
+ break;
+ case 10: /*倾角传感器Y轴倾角*/
+ sprintf(szbuf, "%s Y =%0.3f ", szbuf, fvalue);
+ DebugLog(devparam[devno].commid, szbuf, 'V');
+
+ if((fvalue < -59) ||(fvalue > 59))
+ {
+ frnb = (GeneratingRandomNumber()%101-50)/1000.0;
+ pPortParam->aiValue[1].EuValue *= (1+frnb);
+ }
+ else
+ {
+ pPortParam->aiValue[1].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor\
+ +pPortParam->aiValue[1].AiParam.EuValueDelta;*/
+ }
+ pPortParam->aiValue[1].AiState = Sample;
+ //slantpntmsg[aipnt][1].AiState = 1;
+ break;
+
+ }
+ }
+}
+
+void delete_old_files(const char *path, int days)
+{
+ struct stat file_stat;
+ struct tm *file_tm;
+ time_t now = time(NULL);
+ DIR *dir = opendir(path);
+ struct dirent *entry;
+ char szbuf[1024];
+ char fullpath[256];
+
+ memset(szbuf, 0, sizeof(szbuf));
+ if (!dir)
+ {
+ sprintf(szbuf, "delete_old_files opendir %s error ", path);
+ DebugLog(8, szbuf, 'E');
+ return;
+ }
+
+ while ((entry = readdir(dir)))
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ if (entry->d_type == DT_REG)
+ { // 只处理普通文件
+ snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
+
+ if (stat(fullpath, &file_stat) == -1)
+ {
+ perror("stat");
+ sprintf(szbuf, "stat");
+ DebugLog(8, szbuf, 'E');
+ continue;
+ }
+
+ localtime_r(&(file_stat.st_mtime), file_tm);
+ //file_tm = localtime(&(file_stat.st_mtime));
+
+ if (difftime(now, mktime(file_tm)) > days * 24 * 60 * 60)
+ {
+ if (unlink(fullpath) == -1)
+ { // 删除文件
+ perror("unlink");
+ }
+ }
+ }
+ }
+
+ closedir(dir);
+}
+/*********************************************************************************
+ 把16进制和10进制ASCII字符串转换成int整数
+*********************************************************************************/
+int ATOI(char *buf)
+{
+ int i, ilen, iRetVal;
+
+ if(NULL == buf)
+ return 0;
+ ilen = strlen(buf);
+ if(ilen > 2)
+ {
+ if((buf[0]=='0') && ((buf[1]=='x') || (buf[1]=='X')))
+ {
+ iRetVal = 0;
+ for(i=2; i MAX_SERIAL_DEV_NUM-1))
+ return;
+ srdt.ms_dev[devidx].uOpenPowerFlag = CLOSEPOWER;
+}
+
+
+// 检查传感器电源是否应该关闭或打开
+void Gm_CheckSensorsPower(void)
+{
+ int i, j;
+
+ for(i=0; i srdt.ms_dev[i].ProtocolIdx) ||(INVALID_PROTOCOL<=srdt.ms_dev[i].ProtocolIdx))
+ continue;
+ if((PELCO_P_PROTOCOL == srdt.ms_dev[i].ProtocolIdx) ||(PELCO_D_PROTOCOL == srdt.ms_dev[i].ProtocolIdx)
+ ||( SERIALCAMERA_PROTOCOL == srdt.ms_dev[i].ProtocolIdx))
+ continue;
+ // 需要传感器处于上电状态
+ for(j=0; j rand()%(m-n+1)+n*/
+ ictime = (int)time(NULL);
+ srand((DWORD)ictime);
+ randomdate = rand();
+ return randomdate;
+}
+
+/* 串口启动接口函数 开始*/
+void Collect_sensor_data()
+{
+#if 0
+ int i;
+
+ for(i=0; i datano) || (datano > OpticalRadiationNo))
+ return -1;
+ data->EuValue = weatherpntmsg[datano].EuValue;
+ data->AiState = weatherpntmsg[datano].AiState;
+ if((SampleFail == data->AiState) || (SamplingSuccess == data->AiState))
+ {
+ weatherpntmsg[datano].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetAirTempData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[AirTempNo].EuValue;
+ airt->AiState = weatherpntmsg[AirTempNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[AirTempNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetHumidityData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[HumidityNo].EuValue;
+ airt->AiState = weatherpntmsg[HumidityNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[HumidityNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetWindSpeedData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[WindSpeedNo].EuValue;
+ airt->AiState = weatherpntmsg[WindSpeedNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[WindSpeedNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetWindDirectionData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[WindDirectionNo].EuValue;
+ airt->AiState = weatherpntmsg[WindDirectionNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[WindDirectionNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetRainfallData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[RainfallNo].EuValue;
+ airt->AiState = weatherpntmsg[RainfallNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[RainfallNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetAtmosData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[AtmosNo].EuValue;
+ airt->AiState = weatherpntmsg[AtmosNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[AtmosNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetOpticalRadiationData(Data_DEF *airt)
+{
+ if(NULL == airt)
+ return -1;
+ airt->EuValue = weatherpntmsg[OpticalRadiationNo].EuValue;
+ airt->AiState = weatherpntmsg[OpticalRadiationNo].AiState;
+ if((SampleFail == airt->AiState) || (SamplingSuccess == airt->AiState))
+ {
+ weatherpntmsg[OpticalRadiationNo].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetPullValue(int devno, Data_DEF *data)
+{
+ if(NULL == data)
+ return -1;
+ if((0>devno)||(MAX_SERIAL_DEV_NUM < devno))
+ return -1;
+ if(RALLY_PROTOCOL != devparam[devno].ProtocolIdx)
+ return -1;
+ data->EuValue = srdt.ms_dev[devno].aiValue[0].EuValue;
+ data->AiState = srdt.ms_dev[devno].aiValue[0].AiState;
+ if((SampleFail == data->AiState) || (SamplingSuccess == data->AiState))
+ {
+ srdt.ms_dev[devno].aiValue[0].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetAngleValue(int devno, Data_DEF *data, int Xy)
+{
+ if(NULL == data)
+ return -1;
+ if((0>devno)||(MAX_SERIAL_DEV_NUM < devno))
+ return -1;
+ if(SLANT_PROTOCOL != devparam[devno].ProtocolIdx)
+ return -1;
+ if((0 > Xy) || (1 < Xy))
+ return -1;
+
+ data->EuValue = srdt.ms_dev[devno].aiValue[Xy].EuValue;
+ data->AiState = srdt.ms_dev[devno].aiValue[Xy].AiState;
+ if((SampleFail == data->AiState) || (SamplingSuccess == data->AiState))
+ {
+ srdt.ms_dev[devno].aiValue[Xy].AiState = Idle;
+ return 2;
+ }
+ return 1;
+}
+
+int GetImage(int devno, IMAGE_DEF *photo)
+{
+ if(NULL == photo)
+ return -1;
+ if((0>devno)||(MAX_SERIAL_DEV_NUM < devno))
+ return -1;
+ if((PELCO_D_PROTOCOL != devparam[devno].ProtocolIdx) && (PELCO_P_PROTOCOL != devparam[devno].ProtocolIdx) &&(SERIALCAMERA_PROTOCOL != devparam[devno].ProtocolIdx))
+ return -1;
+ photo->presetno = srdt.ms_dev[devno].image.presetno;
+ photo->phototime = srdt.ms_dev[devno].image.phototime;
+ memset(photo->photoname, 0, sizeof(photo->photoname));
+ memmove(photo->photoname, srdt.ms_dev[devno].image.photoname, sizeof(photo->photoname));
+ photo->imagelen = srdt.ms_dev[devno].image.imagelen;
+ photo->state = srdt.ms_dev[devno].image.state;
+ if((SampleFail == photo->state) || (SamplingSuccess == photo->state))
+ {
+ srdt.ms_dev[devno].image.state = Idle;
+ return 2;
+ }
+ return 1;
+}
+/* 数据和图片采集数据返回函数 结束*/
\ No newline at end of file
diff --git a/app/src/main/cpp/SensorsProtocol.h b/app/src/main/cpp/SensorsProtocol.h
new file mode 100644
index 0000000..6472fe3
--- /dev/null
+++ b/app/src/main/cpp/SensorsProtocol.h
@@ -0,0 +1,467 @@
+//
+// Created by hyz on 2024/6/5.
+//
+
+#ifndef WEATHERCOMM_H
+#define WEATHERCOMM_H
+
+#include
+#include "GPIOControl.h"
+#include "termios.h"
+
+#ifndef DWORD
+typedef unsigned int DWORD;
+#endif
+#ifndef WORD
+typedef unsigned short WORD;
+#endif
+#ifndef BYTE
+typedef unsigned char BYTE;
+#endif
+#ifndef LONG
+typedef long long LONG;
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define LOBYTE(w) ((unsigned char)(w))
+#define HIBYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF))
+
+#define LOWORD(l) ((WORD)(l))
+#define HIWORD(l) ((WORD)((DWORD)(l) >> 16))
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define MAX_STRING_LEN 32
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+
+#define MAX_SERIAL_DEV_NUM 25 /* 最大接串口传感器数量*/
+#define MAX_SERIAL_PORT_NUM 5
+#define MAX_DEV_VALUE_NUM 12 /* 一台装置最大的采样值数量*/
+
+#define WEATHER_PROTOCOL 1 /* 温湿度协议序号*/
+#define WIND_PROTOCOL 2 /* 风速风向协议序号*/
+#define SLANT_PROTOCOL 3 /* 倾斜角协议序号*/
+#define RALLY_PROTOCOL 4 /* 拉力协议序号*/
+#define PELCO_P_PROTOCOL 5 /* 摄像机Pelco_P协议序号*/
+#define PELCO_D_PROTOCOL 6 /* 摄像机Pelco_D协议序号*/
+#define SERIALCAMERA_PROTOCOL 8 /* 串口摄像机协议序号*/
+#define RESERVE2_PROTOCOL 17 /* 备用2协议序号*/
+#define RESERVE4_PROTOCOL 19 /* 备用4协议序号*/
+#define RESERVE5_PROTOCOL 20 /* 备用5协议序号*/
+#define INVALID_PROTOCOL 21 /* 无效协议序号*/
+
+#define AirTempNo 0 /* 空气温度数据存储序号*/
+#define HumidityNo 1 /* 相对湿度数据存储序号*/
+#define WindSpeedNo 2 /* 风速数据存储序号*/
+#define WindDirectionNo 3 /* 风向数据存储序号*/
+#define RainfallNo 4 /* 雨量数据存储序号*/
+#define AtmosNo 5 /* 大气压数据存储序号*/
+#define OpticalRadiationNo 6 /* 日照(光辐射)数据存储序号*/
+
+#define Idle 0 /* 传感器处于空闲状态,未启动采样*/
+#define Sample 1 /* 正在采样过程中*/
+#define SamplingSuccess 2 /* 采样结束,正常读取到数据*/
+#define StartSample 3 /* 启动采样*/
+#define SampleFail -1 /* 采样失败,未采集到数据,传感器故障或未接*/
+#define PHOTO_SAVE_SUCC 5 /* 图片保存成功*/
+
+#define WEATHER_DATA_NUM 8 /* 气象数据最大数量(一般最多是6要素)*/
+#define RALLY_DATA_NUM 2 /* 拉力数据最大数量(一般是1个)*/
+#define SLANTANGLE_DATA_NUM 3 /* 倾角数据最大数量(一般只有X轴和Y轴值)*/
+
+#define PTZ_MOVETIME 1 // 云台移动等待时间为1秒
+#define MAX_CHANNEL_NUM 2 /* 视频通道最大通道*/
+#define MAX_PHOTO_FRAME_LEN 1024 /* 图片数据一包最大长度*/
+#define MAX_PHOTO_PACKET_NUM 1024 /* 图片最大包数(图片最大定为1MB)*/
+
+#define RECVDATA_MAXLENTH 2048 /* 接收数据缓冲区最大值*/
+#define TIMER_CNT 50 // Poll命令定时器时间 5 ms
+#define SENDDATA_MAXLENTH RECVDATA_MAXLENTH /* 正常发送数据缓冲区最大值*/
+
+// 摄像机控制命令宏定义
+#define Cmd_Cancel 0x00000000 // 关闭功能
+#define SET_PRESETNO 0x00030000 // 设置预置点
+#define MOVE_TO_PRESETNO 0x00070000 // 调用预置点
+
+/* 摄像机PELCO-P控制命令宏定义*/
+#define P_Auto_Scan 0x20000000 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/
+#define P_IRIS_CLOSE 0x08000000 /* 光圈缩小(1 有效)*/
+#define P_IRIS_OPEN 0x04000000 /* 光圈放大(1 有效)*/
+#define P_FOCUS_NEAR 0x02000000 /* 近距离聚焦(1 有效)*/
+#define P_FOCUS_FAR 0x01000000 /* 远距离聚焦(1 有效)*/
+#define P_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/
+#define P_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/
+#define P_MOVE_DOWN 0x0010001f /* 向下移动镜头(1 有效)*/
+#define P_MOVE_UP 0x0008001f /* 向上移动镜头(1 有效)*/
+#define P_MOVE_LEFT 0x00041f00 /* 向左移动镜头(1 有效)*/
+#define P_MOVE_RIGHT 0x00021f00 /* 向右移动镜头(1 有效)*/
+
+// 摄像机PELCO-D控制命令宏定义
+#define D_Auto_Scan 0x10000000 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/
+#define D_IRIS_CLOSE 0x04000000 /* 光圈缩小(1 有效)*/
+#define D_IRIS_OPEN 0x02000000 /* 光圈放大(1 有效)*/
+#define D_FOCUS_NEAR 0x01000000 /* 近距离聚焦(1 有效)*/
+#define D_FOCUS_FAR 0x00800000 /* 远距离聚焦(1 有效)*/
+#define D_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/
+#define D_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/
+#define D_MOVE_DOWN 0x0010002d /* 向下移动镜头(1 有效)*/
+#define D_MOVE_UP 0x0008002d /* 向上移动镜头(1 有效)*/
+#define D_MOVE_LEFT 0x00042d00 /* 向左移动镜头(1 有效)*/
+#define D_MOVE_RIGHT 0x00022d00 /* 向右移动镜头(1 有效)*/
+
+/* 摄像机下发命令宏定义*/
+#define Take_Photo 0 /* 拍照*/
+#define Stop_Baud 10000 /* 设置球机波特率*/
+#define Stop_Cmd 10005 /* 取消或停止指令*/
+#define Auto_Scan 10006 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/
+#define IRIS_CLOSE 10007 /* 光圈缩小(1 有效)*/
+#define IRIS_OPEN 10008 /* 光圈放大(1 有效)*/
+#define FOCUS_NEAR 10009 /* 近距离聚焦(1 有效)*/
+#define FOCUS_FAR 10010 /* 远距离聚焦(1 有效)*/
+#define ZOOM_WIDE 10011 /* 远离物体(1 有效)*/
+#define ZOOM_TELE 10012 /* 接近物体(1 有效)*/
+#define MOVE_DOWN 10013 /* 向下移动镜头(1 有效)*/
+#define MOVE_UP 10014 /* 向上移动镜头(1 有效)*/
+#define MOVE_LEFT 10015 /* 向左移动镜头(1 有效)*/
+#define MOVE_RIGHT 10016 /* 向右移动镜头(1 有效)*/
+#define MOVE_PRESETNO 10017 // 调用预置点
+#define SAVE_PRESETNO 10018 // 设置预置点
+#define SPEED_DOME_CAMERA 0 /* 球机摄像机*/
+#define SERIAL_CAMERA 2 /* 串口摄像机a*/
+
+#define COLLECT_DATA 1 /* 调试使用*/
+
+#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args) /* 红色*/
+#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "Sensors_Protocol", fmt, ##args) /* 草绿色*/
+#define LOGV(fmt, args...) __android_log_print(ANDROID_LOG_VERBOSE, "serial_port_comm", fmt, ##args)/* 白色*/
+#define LOGW(fmt, args...) __android_log_print(ANDROID_LOG_WARN, "Sensors_Protocol", fmt, ##args) /* 黄色*/
+#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, "Sensors_Protocol", fmt, ##args) /* 蓝色*/
+#define HexCharToInt( c ) (((c) >= '0') && ((c) <= '9') ? (c) - '0' : ((c) >= 'a') && ((c) <= 'f') ? (c) - 'a' + 10 :((c) >= 'A') && ((c) <= 'F') ? (c) - 'A' + 10 : 0 )
+
+typedef struct
+{
+ int cmd;
+ int value;
+ int result;
+ LONG value2;
+ char str[MAX_STRING_LEN];
+}IOT_PARAM;
+
+//SDS包类型结构
+typedef struct
+{
+ BYTE PortIdx; // 信息类型
+ WORD MsgType; // 信息类型
+ int MsgLen; // 信息长度
+ u_char MsgData[RECVDATA_MAXLENTH];
+} RTUMSG;
+
+typedef struct
+{
+ float fFactor; // 数据系数
+ float EuValueDelta; // 数据工程值偏移
+} AI_PARAM;
+
+typedef struct
+{
+ AI_PARAM AiParam; // 数据点配置参数
+ int AiState; // 数据标识(-1:采样失败;0:没有采样;1:正在采样;2:采样结束;3:启动采样;)
+ float EuValue; // 数据工程值
+} AI_DEF;
+
+typedef struct
+{
+ BYTE AiState; // 数据标识(-1:采样失败;0:没有采样;1:正在采样;2:采样结束;3:启动采样;)
+ float EuValue; // 数据工程值
+} Data_DEF;
+
+typedef struct
+{
+ int imagelen; // 整个图片大小
+ int phototime; // 拍照时间
+ u_char presetno; // 拍照预置点
+ char photoname[512]; // 图片存储名称和路径
+ int state;// 标识(-1:拍照失败;0:没有拍照;1:正在取图;2:拍照成功;3:启动拍照;)
+} IMAGE_DEF;
+
+typedef struct
+{
+ int imagelen; // 整个图片大小
+ int imagenum; // 整个图片的总包数
+ int phototime; // 拍照时间
+ u_char presetno; // 拍照预置点
+ char photoname[512]; // 图片存储名称和路径
+ u_char buf[MAX_PHOTO_PACKET_NUM][MAX_PHOTO_FRAME_LEN]; // 图片数据缓存
+ int ilen[MAX_PHOTO_PACKET_NUM]; // 相对应的每包图片数据的长度
+ int state;// 标识(-1:拍照失败;0:没有拍照;1:正在取图;2:拍照成功;3:启动拍照;)
+} PHOTO_DEF;
+
+// 上层调用采集传感器参数
+typedef struct
+{
+ unsigned int baudrate; /* 波特率*/
+ int databit; /* 数据位*/
+ float stopbit; /* 停止位*/
+ char parity; /* 校验位*/
+ char pathname[64]; /* 串口文件名及路径*/
+ //int commNo; /* 约定的串口序号,例如我们PC机上显示的COM1。。。*/
+ u_char SensorsType; /* 传感器类型索引,大于 0*/
+ int devaddr; /* 装置(传感器)使用的地址*/
+ u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/
+ u_char CameraChannel; /* 像机的通道号*/
+ u_char Phase; /* 传感器所安装相别,指拉力和倾角11表示A1....*/
+} SENSOR_PARAM;
+
+// 需要配置的串口装置参数
+typedef struct
+{
+ unsigned int baudrate; /* 波特率*/
+ int databit; /* 数据位*/
+ int stopbit; /* 停止位*/
+ char parity; /* 校验位*/
+ char pathname[64]; /* 串口文件名及路径*/
+ int commid; /* 串口序号 注意:从0开始*/
+ u_char ProtocolIdx; /* 规约索引,大于 0*/
+ int devaddr; /* 装置使用的地址*/
+ u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/
+ u_char CameraChannel; /* 像机的通道号*/
+ u_char Phase; /* 传感器所安装相别,指拉力和倾角11表示A1....*/
+} SERIAL_PARAM;
+
+typedef struct
+{
+ int m_iRevStatus; /* */
+ int m_iRecvLen; /* */
+ int m_iNeedRevLength; /* */
+ int iRecvTime; /* */
+ u_char m_au8RecvBuf[RECVDATA_MAXLENTH];/* */
+ int fd; /* 串口打开的文件句柄*/
+ u_char PollCmd[SENDDATA_MAXLENTH];
+ int cmdlen; // 发送缓冲区命令长度
+ //******************** Poll Cmd ****************************
+ u_char Retry; /* 重试命令次数 */
+ u_char RetryCnt; /* 重试命令计数*/
+ LONG RetryTime; /* 重试命令时间 */
+ LONG RetryTimeCnt; /* 重试命令时间计数*/
+ LONG WaitTime; /* 命令间隔时间 */
+ LONG WaitTimeCnt; /* 命令间隔时间计数*/
+ u_char ForceWaitFlag; /* 强制等待标志*/
+ u_short ForceWaitCnt; /* 强制等待计数*/
+ u_char ReSendCmdFlag; /* 重发命令标志 */
+ u_char SendCmdFlag; /* 命令发送标志 */
+ u_char RevCmdFlag; /* 命令正常接收标志*/
+ //**********************************************************
+ LONG lsendtime; /* 命令发送绝对时间计时(毫秒)*/
+} SIO_PARAM_SERIAL_DEF;
+
+//串口相关装置所有参数集中定义
+typedef struct
+{
+ //******************** 端口基本信息 ************************
+ u_char IsNeedSerial; /* 是否需要使用串口通讯*/
+ int CmdWaitTime; /* 没有使用*/
+ u_char UseSerialidx; /* 使用的串口序号*/
+ int SerialCmdidx; /* 正在使用的串口发送命令的命令序号(-1:表示没有命令发送)
+ 摄像机使用命令序号存储*/
+ int enrecvtime; /* 发送加密命令后接收到应答计时*/
+ LONG FirstCmdTimeCnt; /* 串口读取数据起始时间*/
+ u_char nextcmd; /* 第二次发送读取气象雨量命令 */
+ u_char SameTypeDevIdx; /* 相同类型装置顺序排列序号(从0开始)*/
+ u_char uOpenPowerFlag; /* 传感器上电标志(0:不需要打开; 1:需要打开)*/
+ int recvdatacnt; /* 接收到有效数据*/
+ PHOTO_DEF image; /* 临时存储图片数据*/
+ AI_DEF aiValue[MAX_DEV_VALUE_NUM]; /* 传感器采样值*/
+} SERIAL_DEV_DEF;
+
+//串口相关装置所有参数集中定义
+typedef struct
+{
+ u_char clcyesampling; /* 正在进行采样(0:没有进行采样;1:正在进行采样;)*/
+ u_char camerauseserial; /* 摄像机使用那个串口*/
+ DWORD PtzCmdType; /* 云台指令类型*/
+ int usecameradevidx; /* 有像机指令需要执行*/
+ /* 执行指令的装置序号(-1:表示没有需要执行的指令;)*/
+ int SendStopPtzCmdTimeCnt; /* 发送云台停止指令*/
+ u_char serialstatus[MAX_SERIAL_PORT_NUM]; /* 串口是否可以使用状态分别对应串口1、2、3*/
+ SERIAL_DEV_DEF ms_dev[MAX_SERIAL_DEV_NUM]; /* 装置所接传感器数量*/
+ int UseingSerialdev[MAX_SERIAL_PORT_NUM]; /* 正在使用串口通讯的装置序号(-1,表示串口空闲)*/
+ int curdevidx[MAX_SERIAL_PORT_NUM]; /* 当前正在通讯的装置序号(-1表示没有装置需要通讯)*/
+ u_char IsReadWireTem; /* 是否在开始读取测温数据(0:表示没有;1:是)*/
+ //int proruntime; /* 程序运行时间*/
+ int IsSleep; /* 是否使程序休眠(1:不休眠;2:休眠)*/
+ int tempsamplingstartime; /* 测温启动距离采样启动时间间隔*/
+ int tempsamplingsucctime; /* 测温启动距离采样成功时间间隔*/
+ int samplingtimeSec; /* 高速采样数据秒级时间控制*/
+ int SectimesamplingCnt[3]; /* 高速采样数据秒级采样数*/
+ int SunshineSensorsFault; /* 控制日照传感器故障发送*/
+ int TempSensorsFault; /* 控制测温传感器故障发送*/
+ int FirstSensorsFault; /* 第一次检测传感器故障发送*/
+ int SensorsIsUse; /* 传感器是否启用与自检位置匹配*/
+ int sequsampling; /* 顺序采样控制序号-1:无采样;其他对应相应装置序号*/
+
+ int imagepacketnum; /* 串口摄像机拍照图片总包数*/
+ int historyimagenum[MAX_CHANNEL_NUM]; /* 球机保存的历史图片数量*/
+#if 1
+ //int sendflag; /* 临时上送泄露电流值标志*/
+ int sendphototime; /* 临时上送图片数据统计*/
+ int sendphotocmdcnt; /* 一次拍照过程中发送拍照指令计数*/
+ int photographtime; /* 图片拍摄的时间*/
+ int iLastGetPhotoNo; /* 设置串口摄像机参数时暂存拍照命令序号*/
+ u_char bImageSize; /* 用于临时存储接收上层命令的图片大小*/
+ u_char presetno; /* 用于临时存储接收上层命令的预置点*/
+ char filedir[512]; /* 用于摄像机拍照之后暂时存放的路径*/
+#endif
+ u_char errorPhotoNoCnt; /* 串口摄像机拍照时回应错误包号计数(如:召第6包回应第3包)*/
+ u_char RephotographCnt; /* 串口摄像机重拍计数(只在读照片数据应答出错时才重拍)*/
+} SRDT_DEF;
+
+static void PortDataProcess( void );
+static LONG get_msec();
+int serial_port_comm();
+static int weather_comm(SERIAL_PARAM weatherport);
+
+static void setRS485Enable(bool z);
+static void set485WriteMode();
+static void set485ReadMode();
+static void set12VEnable(bool z);
+static void setCam3V3Enable(bool enabled);
+
+// 串口相关的所有函数定义
+/* 打开串口电源*/
+void Gm_OpenSerialPower();
+
+// 打开传感器电源
+void Gm_OpenSensorsPower();
+// 关闭传感器电源
+void Gm_CloseSensorsPower(int port);
+
+// 打开串口通讯
+void Gm_OpenSerialPort(int devidx);
+
+// 关闭串口通讯
+void Gm_CloseSerialPort();
+void DebugLog(int commid, char *szbuf, char flag);
+int SaveLogTofile(int commid, char *szbuf);
+// 功能说明:串口发送数据 返回实际发送的字节数
+int GM_SerialComSend(const unsigned char * cSendBuf, LONG nSendLen, int commid);
+void Gm_InitSerialComm(SENSOR_PARAM *sensorParam, char *filedir);
+// 启动串口通讯
+void GM_StartSerialComm();
+// 启动使用串口拍照
+void GM_StartSerialCameraPhoto(BYTE channel, int cmdidx);
+void delete_old_files(const char *path, int days);
+
+// 串口轮询通讯定时器
+int GM_SerialTimer();
+//轮询所有串口和传感器是否需要生成下发命令
+void Gm_FindAllSensorsCommand();
+//检查所有传感器是否采集完毕,采集完毕的关闭传感器电源
+void GM_IsCloseSensors();
+//检查所有串口是否有数据接收,有则启动接收
+void GM_AllSerialComRecv();
+//判断是否需要关闭定时器
+int GM_CloseTimer();
+void testComm();
+void Gm_InitSerialComm_Test();
+// 串口接收数据处理
+void SerialDataProcess(int devidx, u_char *buf, int len);
+
+void CameraRecvData(int commid, u_char *buf, int len);
+
+// 串口摄像机数据处理
+void CameraPhotoPortDataProcess( int port);
+
+// 发送命令
+void SendCmdFormPollCmdBuf( int port );
+
+// 清除发送命令的所有标识
+void ClearCmdAllFlag(int commid);
+
+// 下发串口拍照指令控制
+int FindNextCameraPhotoCommand(int devidx);
+// 生成 CameraPhoto命令
+void MakeCameraPhotoCommand( int portno, BYTE cmdidx, int OneParam, WORD TwoParam, BYTE Threep, int phototime);
+
+// 清除命令缓冲区
+void ClearCmdFormPollCmdBuf(int port);
+
+// 准备发送云台指令
+int Gm_CtrlPtzCmd(u_char channel, DWORD ptzcmd);
+
+// 发送转动摄像机云台命令定时器
+int Gm_Camera_Timer();
+
+// 生成 PELCO_P 命令 *
+void Gm_SendPelco_pCommand( DWORD cmdtype);
+
+// 计算Pelco_p校验
+BYTE Gm_Pelco_pXORCheck( BYTE *msg, int len );
+// 生成 PELCO_D 命令 *
+void Gm_SendPelco_DCommand( DWORD cmdtype);
+
+// 计算Pelco_D校验
+BYTE Gm_Pelco_DCheck( BYTE *msg, int len );
+// 查询传感器电源状态
+char Gm_GetSensorsPowerState(int port);
+
+// 通过传感器使用的航空头查找传感器使用的串口序号
+void FindDevUseSerialCommNo();
+
+// 寻找并生成下一条倾角命令
+int FindNextShxyProtocolCommand( int devidx );
+// 倾角命令校验码计算
+unsigned char CalLpc(unsigned char *msg, int len);
+// 读上海欣影传感器协议数据
+void ShxyProtocolRecvData(int commid, u_char *buf, int len);
+// 检查检验和是否正确
+int CheckShxyProtocolLpcError( u_char* msg, int len );
+
+// 把16进制和10进制ASCII字符串转换成int整数
+int ATOI(char *buf);
+
+//生成倾角命令
+void MakeShxyProtocolPollCommand(int portno, BYTE cmdidx);
+// 上海欣影传感器协议数据处理
+void ShxyProtocolDataProcess( int commid);
+// 控制关闭传感器电源
+//void Gm_CtrlCloseSensorsPower(int devidx);
+// 检查传感器电源是否应该关闭或打开
+//void Gm_CheckSensorsPower(void);
+int SaveImageDataTofile(int devno);
+void Collect_sensor_data();
+
+void CameraPhotoCmd(int phototime, u_char channel, int cmdidx, u_char bImageSize, u_char presetno);
+
+
+/* 数据和图片采集数据返回函数 开始*/
+int GetWeatherData(Data_DEF *data, int datano);
+
+int GetAirTempData(Data_DEF *airt);
+
+int GetHumidityData(Data_DEF *airt);
+
+int GetWindSpeedData(Data_DEF *airt);
+
+int GetWindDirectionData(Data_DEF *airt);
+
+int GetRainfallData(Data_DEF *airt);
+
+int GetAtmosData(Data_DEF *airt);
+
+int GetOpticalRadiationData(Data_DEF *airt);
+
+int GetPullValue(int devno, Data_DEF *data);
+
+int GetAngleValue(int devno, Data_DEF *data, int Xy);
+
+int GetImage(int devno, IMAGE_DEF *photo);
+/* 数据和图片采集数据返回函数 结束*/
+// 生成一个随机整数
+int GeneratingRandomNumber();
+
+#endif //WEATHERCOMM_H
diff --git a/app/src/main/cpp/SerialPort.cpp b/app/src/main/cpp/SerialPort.cpp
new file mode 100644
index 0000000..e035c8d
--- /dev/null
+++ b/app/src/main/cpp/SerialPort.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2009-2011 Cedric Priscal
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "SerialPort.h"
+
+#include "android/log.h"
+static const char *TAG="serial_port";
+#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)
+#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
+#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
+
+static speed_t getBaudrate(int baudrate)
+{
+ switch(baudrate) {
+ case 0: return B0;
+ case 50: return B50;
+ case 75: return B75;
+ case 110: return B110;
+ case 134: return B134;
+ case 150: return B150;
+ case 200: return B200;
+ case 300: return B300;
+ case 600: return B600;
+ case 1200: return B1200;
+ case 1800: return B1800;
+ case 2400: return B2400;
+ case 4800: return B4800;
+ case 9600: return B9600;
+ case 19200: return B19200;
+ case 38400: return B38400;
+ case 57600: return B57600;
+ case 115200: return B115200;
+ case 230400: return B230400;
+ case 460800: return B460800;
+ case 500000: return B500000;
+ case 576000: return B576000;
+ case 921600: return B921600;
+ case 1000000: return B1000000;
+ case 1152000: return B1152000;
+ case 1500000: return B1500000;
+ case 2000000: return B2000000;
+ case 2500000: return B2500000;
+ case 3000000: return B3000000;
+ case 3500000: return B3500000;
+ case 4000000: return B4000000;
+ default: return -1;
+ }
+}
+
+/*
+ * Class: android_serialport_SerialPort
+ * Method: open
+ * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
+ */
+bool SerialPort::Open(std::string path, int baudrate, int flags)
+{
+ speed_t speed;
+
+ /* Check arguments */
+ {
+ speed = getBaudrate(baudrate);
+ if (speed == -1) {
+ /* TODO: throw an exception */
+ LOGE("Invalid baudrate");
+ return false;
+ }
+ }
+
+ /* Opening device */
+ {
+
+ m_fd = open(path.c_str(), O_RDWR | flags);
+ LOGD("open() m_fd = %d", m_fd);
+ if (m_fd == -1)
+ {
+ /* Throw an exception */
+ LOGE("Cannot open port");
+ /* TODO: throw an exception */
+ return false;
+ }
+ }
+
+ /* Configure device */
+ {
+ struct termios cfg;
+ LOGD("Configuring serial port");
+ if (tcgetattr(m_fd, &cfg))
+ {
+ LOGE("tcgetattr() failed");
+ close(m_fd);
+ /* TODO: throw an exception */
+ return false;
+ }
+
+ cfmakeraw(&cfg);
+ cfsetispeed(&cfg, speed);
+ cfsetospeed(&cfg, speed);
+
+ if (tcsetattr(m_fd, TCSANOW, &cfg))
+ {
+ LOGE("tcsetattr() failed");
+ close(m_fd);
+ /* TODO: throw an exception */
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * Class: cedric_serial_SerialPort
+ * Method: close
+ * Signature: ()V
+ */
+bool SerialPort::Close()
+{
+ LOGD("close(m_fd = %d)", m_fd);
+ close(m_fd);
+}
+
diff --git a/app/src/main/cpp/SerialPort.h b/app/src/main/cpp/SerialPort.h
new file mode 100644
index 0000000..28f603a
--- /dev/null
+++ b/app/src/main/cpp/SerialPort.h
@@ -0,0 +1,18 @@
+#ifndef __SERIALPORT_H__
+#define __SERIALPORT_H__
+
+#include
+
+class SerialPort
+{
+public:
+
+ bool Open(std::string path, int, int);
+
+ bool Close();
+
+protected:
+ int m_fd;
+};
+
+#endif // __SERIALPORT_H__
diff --git a/app/src/main/cpp/SpiLib.cpp b/app/src/main/cpp/SpiLib.cpp
new file mode 100644
index 0000000..1934b92
--- /dev/null
+++ b/app/src/main/cpp/SpiLib.cpp
@@ -0,0 +1,1290 @@
+#include "SpiLib.h"
+
+//typedef unsigned char u8;
+
+#define RE_SUC 0x01
+#define RE_ERROR 0x00
+
+
+
+int SpiLIb::spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes)
+{
+ struct spi_ioc_transfer xfer[2];
+ int status;
+
+ memset(xfer, 0, sizeof(xfer));
+
+ xfer[0].tx_buf = (__u64)txbuf;
+ xfer[0].rx_buf = (__u64)rxbuf;
+ xfer[0].len = bytes;
+
+ status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);
+ if (status < 0)
+ {
+ perror("SPI_IOC_MESSAGE");
+ return -1;
+ }
+
+ return status;
+
+}
+
+void SpiLIb::spi_master_init(const char *name, int fd)
+{
+ __u8 mode = 3;
+ __u8 lsb, bits;
+ //__u32 speed = 30000000;
+ __u32 speed = 2000000;
+ //__u32 speed = 2000000;
+ //__u32 speed = 33000000;
+
+ // SPI_IOC_WR_MODE
+
+ ioctl(fd, SPI_IOC_WR_MODE, &mode);
+ ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+
+ if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0)
+ {
+ perror("SPI rd_mode");
+ return;
+ }
+
+ if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
+ {
+ perror("SPI rd_lsb_fist");
+ return;
+ }
+
+ if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
+ {
+ perror("SPI rd bits_per_word");
+ return;
+ }
+
+ if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
+ {
+ perror("SPI rd max_speed_hz");
+ return;
+ }
+
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "%s: spi mode %d, %d bits %sper word, %d Hz max\n", name, mode, bits, lsb ? "(lsb first) " : "", speed);
+ //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
+ // name, mode, bits, lsb ? "(lsb first) " : "", speed);
+}
+
+unsigned char SpiLIb::get_crc7(const unsigned char *buff, int len)
+{
+ unsigned char crc7_accum = 0;
+ int i;
+
+ for (i=0; i < len; i++) {
+ crc7_accum =
+ crc7_table[(crc7_accum << 1) ^ buff[i]];
+ }
+ return crc7_accum;
+}
+
+int SpiLIb::delay(int x)
+{
+ // while (--x);
+ // std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ usleep(50000);
+ return 0;
+}
+
+
+void SpiLIb::SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf)
+{
+ int i=0;
+ int retval;
+
+#if defined (CONFIG_ATMEL_SPI_DEBUG)
+ printf("tx %1d bytes: ", CMD_HEAD_SIZE);
+ for (i = 0; i < CMD_HEAD_SIZE; i++)
+ {
+ printf(" %02x", cmd[i]);
+ }
+ printf("\n");
+#endif
+
+ /* send five command header */
+ for (i=0; i< CMD_HEAD_SIZE; i++)
+ {
+ retval = spi_transfer(fd, cmd+i, rxbuf+i, 1);
+ __android_log_print(ANDROID_LOG_INFO, "SPiCMD", "cmd[%d]=%x,rxbuf[%d]=%x",i,*(cmd+i),i, *(rxbuf+i));
+ delay(20);
+ }
+
+ cmd[0]=0xaa; //for response
+
+}
+
+void SpiLIb::RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins)
+{
+ int retval;
+ int cnt = 1000;
+ int count=0;
+ /* receive ins */
+ INS:
+ txbuf[0] = 0xaa;
+ delay(20);
+ while(cnt--)
+ {
+ retval = spi_transfer(fd, txbuf, buf, 1);
+ __android_log_print(ANDROID_LOG_INFO, "SPiINS", "txbuf=%x,buf=%x", *txbuf,*buf);
+ if(*buf == ins)
+ {
+ return;
+ break;
+ }
+ else
+ goto INS;
+ }
+}
+
+void SpiLIb::RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len)
+{
+
+ int retval;
+ /* receive length */
+ LEN:
+ for(int i=0;i>= 8;
+ memset(Z, entl & 0xFF, 1);
+ memcpy(Z + 2, pucID, idl);
+ memcpy(Z + 2 + idl, abxy, 32 *4);
+ memcpy(Z + 2 + idl + 4 * 32, pubkey, 32);
+ memcpy(Z + 2 + idl + 5 * 32, pubkey+32, 32);
+ nRet = SM3Hash(Z,l,tmpm);
+ if (nRet != 0)
+ goto quit;
+ free(Z);
+ l = inl + 32;
+ Z = (unsigned char *)malloc(l);
+ if (!Z) {
+ nRet = -1;
+ goto quit;
+ }
+ memcpy(Z,tmpm,32);
+ memcpy(Z+32, in, inl);
+ nRet = SM3Hash(Z,l,out);
+ quit:
+ if (Z)
+ free(Z);
+ return nRet;
+}//用于签名的处理哈希值,用户标识01*16
+
+int SpiLIb::SM2Sign(int index,const unsigned char *to_sign,unsigned char *out_sign)//SM2签名 所使用的哈希值应该来源于sm3hash_tosm2
+{
+ int i;
+ int cnt;
+ unsigned char txbuf[256];
+ unsigned char rxbuf[256];
+
+ int retval;
+ int msglen;
+ int fd;
+ const char *devname = "/dev/spidevSE";
+ //const char *devname = "/dev/spidev0.0";
+ //const char *devname = "/dev/mtkgpioctrl";
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0")
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2Sign_CMD[3]=index;
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *) SM2Sign_CMD, sizeof(SM2Sign_CMD));
+
+ SendCmdHeader(fd, txbuf, rxbuf);
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ SendId(fd,txbuf,rxbuf, 0x55);
+
+ memcpy(txbuf, to_sign, 32);
+
+ SendData(fd, txbuf, rxbuf,32);
+
+ SendEnd(fd,txbuf,rxbuf);
+
+ memcpy(txbuf, (const void *) SM2Sign_CMD, sizeof(SM2Sign_CMD));
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ RcvLEN(fd,txbuf,rxbuf+1, 1);
+
+ RcvData(fd, txbuf, rxbuf+2);
+
+ RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90);
+
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ for (i = 2; i < rxbuf[1]+2; i++) {
+ //sprintf(output, " %02x ", rxbuf[i]);
+ out_sign[i-2]= rxbuf[i];
+ }
+
+ close(fd);
+ return 0;
+}
+
+int SpiLIb::SM2VerifySign(int index, unsigned char *hash,unsigned char *vs)//SM2验签
+{
+ unsigned char txbuf[256];
+ unsigned char rxbuf[256];
+
+ int retval;
+ int msglen;
+ int fd;
+ const char *devname = "/dev/spidevSE";
+ //const char *devname = "/dev/spidev0.0";
+ //const char *devname = "/dev/mtkgpioctrl";
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0")
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2VerifySign_CMD[3]=index;
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *) SM2VerifySign_CMD, sizeof(SM2VerifySign_CMD));
+
+ SendCmdHeader(fd, txbuf, rxbuf);
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ SendId(fd,txbuf,rxbuf, 0x55);
+
+ memcpy(txbuf, hash, 32);
+ memcpy(txbuf+32,vs,64);
+
+ SendData(fd, txbuf, rxbuf,96);
+
+ SendEnd(fd,txbuf,rxbuf);
+
+ RcvSW(fd, txbuf, rxbuf, 0x90);
+
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+
+
+ close(fd);
+ return 0;
+}
+
+int SpiLIb::SM2encrypt(int index,unsigned char *to_encrypt ,unsigned char *out_encrypt)//加密
+{
+ int i;
+ int cnt;
+ unsigned char txbuf[512];
+ unsigned char rxbuf[512];
+
+ int retval;
+ int msglen;
+ int fd;
+ const char *devname = "/dev/spidevSE";
+ //const char *devname = "/dev/spidev0.0";
+ //const char *devname = "/dev/mtkgpioctrl";
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0")
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2encrypt_CMD[3]=index;
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *) SM2encrypt_CMD, sizeof(SM2encrypt_CMD));
+
+ SendCmdHeader(fd, txbuf, rxbuf);
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ SendId(fd,txbuf,rxbuf, 0x55);
+
+ memcpy(txbuf, to_encrypt, 32);
+
+ SendData(fd, txbuf, rxbuf,32);
+
+ SendEnd(fd,txbuf,rxbuf);
+
+ memcpy(txbuf, (const void *) SM2encrypt_CMD, sizeof(SM2encrypt_CMD));
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ RcvLEN(fd,txbuf,rxbuf+1, 1);
+
+ RcvData(fd, txbuf, rxbuf+2);
+
+ RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ for (i = 2; i < rxbuf[1]+2; i++) {
+ //sprintf(output, " %02x ", rxbuf[i]);
+ out_encrypt[i-2]= rxbuf[i];
+ }
+
+ close(fd);
+ return 0;
+}
+int SpiLIb::SM2decoder(int index,unsigned char *to_decoder ,unsigned char *out_decoder)//解密
+{
+ int i;
+ int cnt;
+ unsigned char txbuf[512];
+ unsigned char rxbuf[512];
+
+ int retval;
+ int msglen;
+ int fd;
+ const char *devname = "/dev/spidevSE";
+ //const char *devname = "/dev/spidev0.0";
+ //const char *devname = "/dev/mtkgpioctrl";
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0")
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2decoder_CMD[3]=index;
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *) SM2decoder_CMD, sizeof(SM2decoder_CMD));
+
+ SendCmdHeader(fd, txbuf, rxbuf);
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ SendId(fd,txbuf,rxbuf, 0x55);
+
+ memcpy(txbuf, to_decoder, 128);
+
+ SendData(fd, txbuf, rxbuf,128);
+
+ SendEnd(fd,txbuf,rxbuf);
+
+ memcpy(txbuf, (const void *) SM2decoder_CMD, sizeof(SM2decoder_CMD));
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]);
+
+ RcvLEN(fd,txbuf,rxbuf+1, 1);
+
+ RcvData(fd, txbuf, rxbuf+2);
+
+ RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ for (i = 2; i < rxbuf[1]+2; i++) {
+ //sprintf(output, " %02x ", rxbuf[i]);
+ out_decoder[i-2]= rxbuf[i];
+ }
+
+ close(fd);
+ return 0;
+}
+
+int SpiLIb::SM2cert(int type,int index,string cert,unsigned char *out_cert)//证书
+{
+ int i;
+ int cnt;
+ unsigned char txbuf[512];
+ unsigned char rxbuf[1024];
+
+ int retval;
+ int msglen;
+ int fd;
+ const char *devname = "/dev/spidevSE";
+ //const char *devname = "/dev/spidev0.0";
+ //const char *devname = "/dev/mtkgpioctrl";
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0")
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+
+ int certlen=cert.length();
+ unsigned char to_cert[certlen];
+ for(int x=0;x
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+using namespace std;
+
+#define CMD_HEAD_SIZE 5
+using namespace std;
+typedef unsigned char u8;
+
+class SpiLIb{
+public:
+ int Spirandom();
+ int Version();
+ int Indentify(unsigned char *to_idt,unsigned char *out_idt);
+ int SM2keypair(int index);
+ int SM2OutPub(int index,unsigned char result[]);
+ int SM2OutPri(int index,unsigned char result[]);
+ int SM2InPub(int index,const unsigned char new_key[]);
+ int SM2InPri(int index,const unsigned char new_key[]);
+ int SM3Hash(unsigned char *to_hash ,int len,unsigned char *out_hash);
+ int sm3hash_tosm2(unsigned char *in,int inl,unsigned char *out, unsigned char *pubkey, unsigned char
+ *pucID, int idl);
+ int SM2Sign(int index,const unsigned char *to_sign,unsigned char *out_sign);
+ int SM2VerifySign(int index,unsigned char *hash,unsigned char *vs);
+ int SM2encrypt(int index,unsigned char *to_encrypt ,unsigned char *out_encrypt);
+ int SM2decoder(int index,unsigned char *to_decoder ,unsigned char *out_decoder);
+ int SM2cert(int type,int index,string cert,unsigned char *out_cert);
+
+
+
+
+private:
+ const unsigned char crc7_table[256]= {
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
+ 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
+ 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
+ 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
+ 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
+ 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
+ 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
+ 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
+ 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
+ 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
+ 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
+ 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
+ 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
+ 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
+ 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
+ };
+ const unsigned char EK_CMD[5]={0x80,0xd4,0x01,0x00,0x10};
+ const unsigned char AK_CMD[5]={0x80,0xd4,0x02,0x00,0x10};
+ const unsigned char IV_CMD[5]={0x80,0xd4,0x04,0x00,0x10};
+ volatile unsigned char SM1encrpt_CMD[5]={0xa0,0xe0,0x80,0xff,0xff};
+ volatile unsigned char SM1decoder_CMD[5]={0xa0,0xe0,0x81,0xff,0xff};
+ volatile unsigned char SM2Keypair_CMD[5]={0x80,0xb2,0x00,0xff,0x00};
+ volatile unsigned char SM2OutPub_CMD[5]={0x80,0xb8,0x01,0xff,0x40};
+ volatile unsigned char SM2OutPri_CMD[5]={0x80,0xb8,0x02,0xff,0x20};
+ volatile unsigned char SM2InPub_CMD[5]={0x80,0xba,0x01,0xff,0x40};
+ volatile unsigned char SM2InPri_CMD[5]={0x80,0xba,0x02,0xff,0x20};
+ volatile unsigned char SM3Hash_CMD[5]={0x80,0xb5,0x00,0xff,0xff};
+ volatile unsigned char SM2Sign_CMD[5]={0x80,0xb4,0x00,0xff,0x20};
+ volatile unsigned char SM2VerifySign_CMD[5]={0x80,0xb6,0x00,0xff,0x60};
+ volatile unsigned char SM2encrypt_CMD[5]={0x80,0xb3,0x01,0xff,0x20};
+ volatile unsigned char SM2decoder_CMD[5]={0x80,0xb3,0x81,0xff,0x80};
+ volatile unsigned char SM2cert_CMD[5]={0x80,0xb7,0xff,0xff,0xff};
+ volatile unsigned char Random_CMD[5]={0x00,0x84,0x00,0x00,0xff};
+ const unsigned char Version_CMD[5]={0x00,0x5b,0x00,0x00,0x40};
+ const unsigned char Indentify_CMD[5]={0x80,0xb3,0x01,0x04,0x20};
+
+ int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes);
+ void spi_master_init(const char *name, int fd);
+ unsigned char get_crc7(const unsigned char *buff, int len);
+ void SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf);
+ int delay(int x);
+ void RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins);
+ void RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len);
+ void RcvData(int fd, u8 *txbuf, u8 *buf);
+ void RcvData(int fd, u8 *txbuf, u8 *buf, int len);
+ void RcvSW(int fd, u8 *txbuf, u8 *buf, u8 sw);
+ void SendEnd(int fd, u8 *txbuf, u8 *buf);
+ void SendId(int fd, u8 *txbuf, u8 *buf, u8 id);
+ void SendData(int fd,u8 *data, u8 *rxbuf,int data_size);
+
+
+
+};
+
+
+
+
+#endif //TESTCOMM_SPILIB_H
diff --git a/app/src/main/cpp/SpiPort.cpp b/app/src/main/cpp/SpiPort.cpp
new file mode 100644
index 0000000..44e1afb
--- /dev/null
+++ b/app/src/main/cpp/SpiPort.cpp
@@ -0,0 +1,62 @@
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "SpiPort.h"
+
+SpiPort::SpiPort(const std::string& path) : m_path(path), m_fd(0)
+{
+}
+
+SpiPort::~SpiPort()
+{
+ if (m_fd > 0)
+ {
+ close(m_fd);
+ }
+}
+
+bool SpiPort::Open()
+{
+ if(m_fd <= 0) m_fd = open(m_path.c_str(), O_RDWR/*|O_NDELAY|O_NOCTTY*/);
+ if(m_fd <= 0 ) {
+ int err = errno;
+ m_log = "open spi Error errno=" + std::to_string(err);
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "open spi Error errno=%d", err);
+ return false;
+ }
+ else __android_log_print(ANDROID_LOG_INFO, "SPi", "open spi Success m_fd=%d",m_fd);
+
+ return true;
+}
+
+// write
+int SpiPort::Write(unsigned char *buf, int len)
+{
+ return write(m_fd, buf, len);
+}
+
+// read
+int SpiPort::Read(unsigned char *buf, int len)
+{
+ return read(m_fd, buf, len);
+}
+
+//close
+bool SpiPort::Close()
+{
+ if(m_fd > 0)
+ {
+ close(m_fd);
+ m_fd = 0;
+ }
+
+ return true;
+}
\ No newline at end of file
diff --git a/app/src/main/cpp/SpiPort.h b/app/src/main/cpp/SpiPort.h
new file mode 100644
index 0000000..a4d8269
--- /dev/null
+++ b/app/src/main/cpp/SpiPort.h
@@ -0,0 +1,30 @@
+#ifndef _SPIPORT_H_
+#define _SPIPORT_H_
+
+#include
+
+class SpiPort
+{
+public:
+
+ SpiPort(const std::string& path);
+ ~SpiPort();
+
+ bool Open();
+ int Write(unsigned char *buf, int len);
+ int Read(unsigned char *buf, int len);
+
+ bool Close();
+
+ std::string GetLog() const
+ {
+ return m_log;
+ }
+
+protected:
+ std::string m_path;
+ std::string m_log;
+ int m_fd;
+};
+
+#endif
\ No newline at end of file
diff --git a/app/src/main/cpp/WeatherComm.cpp b/app/src/main/cpp/WeatherComm.cpp
new file mode 100644
index 0000000..b0b2630
--- /dev/null
+++ b/app/src/main/cpp/WeatherComm.cpp
@@ -0,0 +1,595 @@
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "GPIOControl.h"
+#include "WeatherComm.h"
+#include
+
+SIO_PARAM_SERIAL_DEF serialport;
+float weatherpntmsg[10];
+
+static void set_baudrate (struct termios *opt, unsigned int baudrate)
+{
+ cfsetispeed(opt, baudrate);
+ cfsetospeed(opt, baudrate);
+}
+
+static void set_data_bit (struct termios *opt, unsigned int databit)
+{
+ opt->c_cflag &= ~CSIZE;
+ switch (databit)
+ {
+ case 8:
+ opt->c_cflag |= CS8;
+ break;
+ case 7:
+ opt->c_cflag |= CS7;
+ break;
+ case 6:
+ opt->c_cflag |= CS6;
+ break;
+ case 5:
+ opt->c_cflag |= CS5;
+ break;
+ default:
+ opt->c_cflag |= CS8;
+ break;
+ }
+}
+
+static void set_parity (struct termios *opt, char parity)
+{
+ switch (parity)
+ {
+ case'N':/* 无校验 */
+ case 'n':
+ opt->c_cflag &= ~PARENB;
+ break;
+ case'E':/*偶校验*/
+ case 'e':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag &= ~PARODD;
+ break;
+ case'O':/* 奇校验 */
+ case 'o':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag |= ~PARODD;
+ break;
+ default: /*其它选择为无校验 */
+ opt->c_cflag &= ~PARENB;
+ break;
+ }
+}
+
+static void set_stopbit (struct termios *opt, const char *stopbit)
+{
+ if (strcmp(stopbit, "1") == 0)
+ {
+ opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */
+ }
+ else if(0 == strcmp(stopbit, "1.5"))
+ {
+ opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */
+ }
+ else if(0 == strcmp (stopbit,"2"))
+ {
+ opt->c_cflag |= CSTOPB; /*2 位停止位 */
+ }
+ else
+ {
+ opt->c_cflag &= ~CSTOPB; /*1 位停止位 */
+ }
+}
+
+int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin )
+{
+ struct termios opt;
+ tcgetattr(fd, &opt);
+ set_baudrate(&opt, baudrate);
+ //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */
+ opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG);
+ set_data_bit(&opt, databit);
+ set_parity(&opt, parity);
+ set_stopbit(&opt, stopbit);
+ opt.c_iflag &=~(INLCR|ICRNL);
+ opt.c_iflag &=~(IXON);/* 流控*/
+ opt.c_oflag = 0;
+ //opt.c_lflag |= 0;
+ opt.c_oflag &= ~OPOST;
+ opt.c_cc[VTIME] = vtime;
+ opt.c_cc[VMIN] = vmin;
+ tcflush (fd, TCIFLUSH);
+ return (tcsetattr (fd, TCSANOW, &opt));
+}
+
+static void setInt(int cmd, int value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value = value;
+ // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
+ if( fd > 0 )
+ {
+ int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+ close(fd);
+ }
+ return;
+}
+static void setRS485Enable(bool z) {
+ setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
+}
+
+static void set485WriteMode() {
+ setInt(CMD_SET_485_STATE, 1);
+}
+
+static void set485ReadMode() {
+ setInt(CMD_SET_485_STATE, 0);
+}
+static void set12VEnable(bool z) {
+ setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
+}
+
+static void setCam3V3Enable(bool enabled)
+{
+ setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
+}
+
+
+/*********************************************************************************
+* 气象数据处理 *
+**********************************************************************************/
+void PortDataProcess( )
+{
+ float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
+ //WORD uDevAddr;
+ unsigned char cmdidx;
+ int i, j, aipnt, datanum;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+ char szbuf[64];
+
+ pPortParam = &serialport;
+ //取出装置地址,开始处理地址+++
+ if(0x02 == pPortParam->m_au8RecvBuf[5])
+ {
+ //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4];
+ return;
+ }
+ cmdidx = pPortParam->m_au8RecvBuf[5];
+#if 0
+ aipnt = pPortParam->SameTypeDevIdx;
+ uDevAddr = serialport->m_au8RecvBuf[4];
+ if(0 == srdt.IsReadWireTem)
+ {
+ if(uDevAddr != pPortParam->devaddr)
+ return;
+ }
+#endif
+ fvalua = &fvalue;
+ datanum = pPortParam->m_au8RecvBuf[6];
+ if((0x08 != cmdidx) && (0x09 != cmdidx))
+ return;
+
+ for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 )
+ {
+ if(0x08 == cmdidx)
+ fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16)
+ +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4];
+ else
+ {
+ *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4];
+ *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3];
+ *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2];
+ *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1];
+ }
+ switch(pPortParam->m_au8RecvBuf[j])
+ {
+ case 1: /*温度*/
+ weatherpntmsg[0] = fvalue;
+ LOGE("温度:%0.3f ", fvalue);
+ break;
+ case 2: /*气压*/
+ weatherpntmsg[5] = fvalue;
+ LOGE("气压:%0.3f ", fvalue);
+ break;
+ case 3: /*湿度*/
+ weatherpntmsg[1] = fvalue;
+ LOGE("湿度:%0.3f ", fvalue);
+ break;
+ case 4: /*雨量*/
+ break;
+ case 5: /*日照*/
+ break;
+ case 6: /*风速*/
+ weatherpntmsg[2] = fvalue;
+ LOGE("风速:%0.3f ", fvalue);
+ break;
+ case 7: /*风向*/
+ weatherpntmsg[3] = fvalue;
+ LOGE("风向:%0.3f ", fvalue);
+ break;
+ case 8: /*拉力*/
+ LOGE("拉力:%0.3f ", fvalue);
+ break;
+ case 9: /*倾角传感器X轴倾角*/
+ LOGE("X:%0.3f ", fvalue);
+ break;
+ case 10: /*倾角传感器Y轴倾角*/
+ LOGE("Y:%0.3f ", fvalue);
+ break;
+ case 11: /*测温球导线温度*/
+ case 12: /*测温球内部温度*/
+ break;
+ case 13: /*测温球导线X轴倾角*/
+ break;
+ case 14: /*测温球导线Y轴倾角*/
+ break;
+ case 15: /*测温球导线电流*/
+ break;
+ case 16: /*测温球电池电压*/
+ break;
+ case 17: /*A相泄漏电流平均值;*/
+ break;
+ case 18: /*A相泄漏电流最大值;*/
+ break;
+ case 19: /*A相超过3mA的脉冲频次*/
+ break;
+ case 20: /*A相超过10mA的脉冲频次*/
+ break;
+ case 21: /*B相泄漏电流平均值;*/
+ break;
+ case 22: /*B相泄漏电流最大值;*/
+ break;
+ case 23: /*B相超过3mA的脉冲频次*/
+ break;
+ case 24: /*B相超过10mA的脉冲频次*/
+ case 25: /*C相泄漏电流平均值;*/
+ case 26: /*C相泄漏电流最大值;*/
+ case 27: /*C相超过3mA的脉冲频次*/
+ case 28: /*C相超过10mA的脉冲频次*/
+ break;
+ }
+ }
+}
+
+//***************************************************************
+//* 按照协议格式化接收数据 *
+//***************************************************************
+static void RecvData(u_char *buf, int len)// 规约读数据处理
+{
+ int i, ictime;
+ //WORD crc, check;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ pPortParam = &serialport;
+ ictime = (int)time(NULL);
+
+ if(pPortParam->m_iRecvLen == 0)
+ {
+ pPortParam->iRecvTime = ictime;
+ }
+ else
+ {
+ if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0))
+ pPortParam->iRecvTime = ictime;
+ else if(ictime - pPortParam->iRecvTime > 2)
+ {
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_iRevStatus = 0;
+ }
+ }
+
+ for(i=0; im_iRevStatus)
+ {
+ case 0: // 0x68
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 1: // len1
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ break;
+ case 2: // len2
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ //if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2])
+ {
+ pPortParam->m_iRevStatus++;
+ pPortParam->m_iNeedRevLength = buf[i]+5;
+ }
+ //else
+ // pPortParam->m_iRevStatus = 18;
+ break;
+ case 3: // 0x68
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iNeedRevLength--;
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 4: // 正确接收数据
+ pPortParam->m_iNeedRevLength--;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iNeedRevLength > 0)
+ break;
+ if(buf[i] != 0x16)
+ {
+ pPortParam->m_iRevStatus=18;
+ break;
+ }
+
+ //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE)
+ {
+ PortDataProcess();
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->RevCmdFlag = 1;
+ }
+ pPortParam->m_iRecvLen = 0;
+ break;
+ case 255:// 错误接收数据
+ default:
+ if(buf[i] == 0x68)
+ {
+ pPortParam->m_iRevStatus = 1;
+ pPortParam->m_iRecvLen = 1;
+ pPortParam->m_au8RecvBuf[0] = buf[i];
+ }
+ else if(buf[i] == 0x16)
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->m_iRecvLen = 0;
+ }
+ else
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iRecvLen > 200)
+ {
+ pPortParam->m_iRecvLen = 0;
+ }
+ }
+ break;
+ }
+ }
+}
+
+static long get_msec(void )
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ long time_in_msec = tv.tv_sec * 1000 + tv.tv_usec/1000;
+
+ return time_in_msec;
+}
+//int inum =0;
+//int itimecnt=0;
+static int weather_comm(SERIAL_PARAM weatherport)
+{
+ int fd = -1;
+ int len, i,ret, icnt=0;
+ long ictime, iruntime, isendtime, irecvtime;
+ //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0D,0x09,0x16,0x16};
+ unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0A,0x16};
+ //unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0ff,0x02,0x01,0x16};
+ //unsigned char sendbuf[] = {0x68,0x01,0x01,0x68,0x02,0x01,0x01,0x04, 0x16};
+ char recvbuf[256], szbuf[512];
+ //char serial_description[] = "/dev/ttyS0";
+
+#if 0
+ DIR *dir = opendir("/dev");
+ if (dir == NULL) {
+ LOGE("_test_ opendir");
+ return -1;
+ }
+
+ // 读取目录项
+ struct dirent *entry;
+ while ((entry = readdir(dir)) != NULL) {
+ // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头
+ if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
+ (strncmp(entry->d_name, "ttyS0", 5) == 0)) {
+ LOGE("_test_ Found serial port: %s\n", entry->d_name);
+ }
+ }
+
+ // 关闭目录
+ closedir(dir);
+#endif
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+
+ set12VEnable(true);
+ setCam3V3Enable(true);
+ setRS485Enable(true);
+ setInt(CMD_SET_WTH_POWER, 1);
+ setInt(CMD_SET_PULL_POWER, 1);
+ setInt(CMD_SET_ANGLE_POWER, 1);
+ setInt(CMD_SET_OTHER_POWER, 1);
+ setInt(CMD_SET_PIC1_POWER, 1);
+#if 1
+ setInt(CMD_SET_485_en0, 1);
+ setInt(CMD_SET_485_en1, 1);
+ setInt(CMD_SET_485_en2, 1);
+ setInt(CMD_SET_485_en3, 1);
+ setInt(CMD_SET_485_en4, 1);
+#else
+ setInt(CMD_SET_485_en0, 0);
+ setInt(CMD_SET_485_en1, 0);
+ setInt(CMD_SET_485_en2, 0);
+ setInt(CMD_SET_485_en3, 0);
+ setInt(CMD_SET_485_en4, 0);
+#endif
+ sleep(3);
+ //ictime = (int)time(NULL);
+ ictime = get_msec();
+ for(;;)
+ {
+ if(fd < 0)
+ {
+ fd = open(weatherport.pathname, O_RDWR | O_NDELAY);
+ //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY);
+ if(fd < 0)
+ {
+ LOGE("open serial %s fail!", weatherport.pathname);
+ //perror(weatherport.pathname);
+ return -1;
+ } else
+ LOGE("open serial %s success!", weatherport.pathname);
+
+
+ ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */
+ if(ret < 0)
+ {
+ LOGE("_test_ set uart arrt faile \n");
+ return -1;
+ }
+ }
+ //tcdrain(fd);
+ //sleep(2);
+ usleep(100);
+ //iruntime = (int)time(NULL);
+ iruntime = get_msec();
+ if((iruntime - ictime > 120000) || (iruntime - ictime < 0))
+ ictime = iruntime;
+ if(iruntime - ictime > 20000)
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0);
+ LOGE("%s", szbuf);
+ break;
+ }
+
+ if(1 == serialport.RevCmdFlag)
+ {
+ //set485WriteMode();
+
+ len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
+ serialport.RevCmdFlag = 0;
+ LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime);
+ //isendtime = time(NULL);
+ isendtime = get_msec();
+ if (len < 0) {
+ LOGE("write data error \n");
+ return -1;
+ } else {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Send:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]);
+ }
+ LOGE("%s", szbuf);
+ //icnt = 0;
+ //inum++;
+ }
+ //tcdrain(fd);
+ //usleep(50000);
+ }
+ else
+ {
+ //irecvtime = time(NULL);
+ irecvtime = get_msec();
+ if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0))
+ isendtime = irecvtime;
+ if (irecvtime-isendtime > 500)
+ {
+ LOGE("传感器超过%ld毫秒未应答", irecvtime-isendtime);
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+ //close(fd);
+ //set12VEnable(false);
+ //setCam3V3Enable(false);
+ //setRS485Enable(false);
+ //fd = -1;
+ continue;
+ }
+ }
+ //set485ReadMode();
+ memset(recvbuf, 0, sizeof(recvbuf));
+ len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */
+ if (len < 0) {
+ LOGE("serial read error \n");
+ continue;
+ }
+ if(0 == len)
+ {
+ //icnt++;
+ continue;
+ }
+
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Recv:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]);
+ }
+ __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf);
+ RecvData((u_char*)recvbuf, len);
+ //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt);
+ icnt = 0;
+ //serialport.RevCmdFlag =1;
+ }
+
+ close(fd);
+ set12VEnable(false);
+ setCam3V3Enable(false);
+ setRS485Enable(false);
+
+ //exit(-1);
+ return(0);
+}
+
+int serial_port_comm()
+{
+ SERIAL_PARAM portparm;
+
+ //struct timeval tv;
+
+ //gettimeofday(&tv, NULL);
+ //long time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec;
+
+ //LOGE("Current time in microseconds: %ld\n", time_in_microseconds);
+
+#if 1
+ memset(portparm.pathname, 0, sizeof(portparm.pathname));
+ //sprintf(portparm.pathname, "/dev/ttyS1");
+ sprintf(portparm.pathname, "/dev/ttysWK3");
+ portparm.parity = 'N';
+ portparm.databit = 8;
+ portparm.baudrate = B9600;
+ memset(portparm.stopbit, 0, sizeof(portparm.stopbit));
+ sprintf(portparm.stopbit, "1");
+#endif
+ //itimecnt = (int)time(NULL);
+
+ for(;;)
+ {
+ sleep(3);
+ weather_comm(portparm);
+ }
+
+ return 0;
+}
+
diff --git a/app/src/main/cpp/WeatherComm.h b/app/src/main/cpp/WeatherComm.h
new file mode 100644
index 0000000..3a9d311
--- /dev/null
+++ b/app/src/main/cpp/WeatherComm.h
@@ -0,0 +1,51 @@
+//
+// Created by hyz on 2024/6/5.
+//
+
+#ifndef WEATHERCOMM_H
+#define WEATHERCOMM_H
+
+#include
+#include "GPIOControl.h"
+
+#define MAX_STRING_LEN 32
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+
+#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args)
+
+// 串口参数
+typedef struct
+{
+ int baudrate; /* 波特率*/
+ int databit; /* 数据位*/
+ char stopbit[8]; /* 停止位*/
+ char parity; /* 校验位*/
+ char pathname[128];/* 串口文件名及路径*/
+} SERIAL_PARAM;
+
+typedef struct
+{
+ int m_iRevStatus; /* */
+ int m_iRecvLen; /* */
+ int m_iNeedRevLength; /* */
+ int iRecvTime; /* */
+ int RevCmdFlag;
+ unsigned char m_au8RecvBuf[128];/* */
+} SIO_PARAM_SERIAL_DEF;
+
+typedef struct
+{
+ int cmd;
+ int value;
+ int result;
+ long value2;
+ char str[MAX_STRING_LEN];
+}IOT_PARAM;
+
+void PortDataProcess( );
+int serial_port_comm();
+static int weather_comm(SERIAL_PARAM weatherport);
+int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin );
+
+#endif //WEATHERCOMM_H
diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp
new file mode 100644
index 0000000..ed200d8
--- /dev/null
+++ b/app/src/main/cpp/native-lib.cpp
@@ -0,0 +1,1028 @@
+#include
+#include
+
+#include "SpiPort.h"
+#include "SpiLib.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "GPIOControl.h"
+#include "serialComm.h"
+#include "SensorsProtocol.h"
+#include "WeatherComm.h"
+
+#if 0
+#define BYTE u_char;
+// 串口参数
+typedef struct
+{
+ int baudrate; /* 波特率*/
+ int databit; /* 数据位*/
+ char stopbit[8]; /* 停止位*/
+ char parity; /* 校验位*/
+ char pathname[128];/* 串口文件名及路径*/
+ } SERIAL_PARAM;
+
+typedef struct
+{
+ int m_iRevStatus; /* */
+ int m_iRecvLen; /* */
+ int m_iNeedRevLength; /* */
+ int iRecvTime; /* */
+ int RevCmdFlag;
+ unsigned char m_au8RecvBuf[128];/* */
+} SIO_PARAM_SERIAL_DEF;
+
+extern SIO_PARAM_SERIAL_DEF serialport;
+extern float weatherpntmsg[10];
+#endif
+
+int istop=1;
+//set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin )
+class NrsecSpiPort : public SpiPort {
+public:
+ NrsecSpiPort(const std::string& path) : SpiPort(path) {
+
+ }
+
+ bool Open()
+ {
+ if (!SpiPort::Open())
+ {
+ return false;
+ }
+
+ uint8_t mode = SPI_MODE_3;
+ uint8_t bits = 8;
+ uint32_t speed = 33000000;
+ uint8_t lsb = 1;
+ // const char *device = "/dev/spidev32766.1";
+
+ if (ioctl(m_fd, SPI_IOC_WR_MODE, &mode) == -1 ||
+ ioctl(m_fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1 ||
+ ioctl(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1 ||
+ ioctl(m_fd, SPI_IOC_WR_LSB_FIRST, &lsb) == -1)
+ {
+ Close();
+ return false;
+ }
+
+ return true;
+ }
+ bool GenKeyPair(int keyIdx) {
+ unsigned char header[] = {0x80, 0xb2, 0x00, (unsigned char)keyIdx, 0x00 };
+
+ int bytesWriten = Write(header, sizeof(header));
+ unsigned char buffer[2] = { 0 };
+ int bytesRead = Read(buffer, sizeof(buffer));
+ if (bytesRead > 0) {
+ int aa = 0;
+ } else {
+ int bb = 0;
+ }
+
+ return true;
+ }
+};
+
+#if 0
+static void set_baudrate (struct termios *opt, unsigned int baudrate)
+{
+ cfsetispeed(opt, baudrate);
+ cfsetospeed(opt, baudrate);
+}
+
+static void set_data_bit (struct termios *opt, unsigned int databit)
+{
+ opt->c_cflag &= ~CSIZE;
+ switch (databit)
+ {
+ case 8:
+ opt->c_cflag |= CS8;
+ break;
+ case 7:
+ opt->c_cflag |= CS7;
+ break;
+ case 6:
+ opt->c_cflag |= CS6;
+ break;
+ case 5:
+ opt->c_cflag |= CS5;
+ break;
+ default:
+ opt->c_cflag |= CS8;
+ break;
+ }
+}
+
+static void set_parity (struct termios *opt, char parity)
+{
+ switch (parity)
+ {
+ case'N':/* 无校验 */
+ case 'n':
+ opt->c_cflag &= ~PARENB;
+ break;
+ case'E':/*偶校验*/
+ case 'e':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag &= ~PARODD;
+ break;
+ case'O':/* 奇校验 */
+ case 'o':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag |= ~PARODD;
+ break;
+ default: /*其它选择为无校验 */
+ opt->c_cflag &= ~PARENB;
+ break;
+ }
+}
+
+static void set_stopbit (struct termios *opt, const char *stopbit)
+{
+ if (strcmp(stopbit, "1") == 0)
+ {
+ opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */
+ }
+ else if(0 == strcmp(stopbit, "1.5"))
+ {
+ opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */
+ }
+ else if(0 == strcmp (stopbit,"2"))
+ {
+ opt->c_cflag |= CSTOPB; /*2 位停止位 */
+ }
+ else
+ {
+ opt->c_cflag &= ~CSTOPB; /*1 位停止位 */
+ }
+}
+
+int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin )
+{
+ struct termios opt;
+ tcgetattr(fd, &opt);
+ set_baudrate(&opt, baudrate);
+ //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */
+ opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG);
+ set_data_bit(&opt, databit);
+ set_parity(&opt, parity);
+ set_stopbit(&opt, stopbit);
+ opt.c_oflag = 0;
+ //opt.c_lflag |= 0;
+ opt.c_oflag &= ~OPOST;
+ opt.c_cc[VTIME] = vtime;
+ opt.c_cc[VMIN] = vmin;
+ tcflush (fd, TCIFLUSH);
+ return (tcsetattr (fd, TCSANOW, &opt));
+}
+#define MAX_STRING_LEN 32
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+
+typedef struct
+{
+ int cmd;
+ int value;
+ int result;
+ long value2;
+ char str[MAX_STRING_LEN];
+}IOT_PARAM;
+
+#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args)
+#endif
+void setInt(int cmd, int value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value = value;
+ // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
+ if( fd > 0 )
+ {
+ int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+ close(fd);
+ }
+ return;
+}
+static void setRS485Enable(bool z) {
+ setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
+}
+
+static void set485WriteMode() {
+ setInt(CMD_SET_485_STATE, 1);
+}
+
+
+static void set485ReadMode() {
+ setInt(CMD_SET_485_STATE, 0);
+}
+static void set12VEnable(bool z) {
+ setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
+}
+#if 0
+static void setCam3V3Enable(bool enabled)
+{
+ setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
+}
+
+/*********************************************************************************
+* 气象数据处理 *
+**********************************************************************************/
+void PortDataProcess( void )
+{
+ float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
+ //WORD uDevAddr;
+ unsigned char cmdidx;
+ int i, j, aipnt, datanum;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+ char szbuf[64];
+
+ pPortParam = &serialport;
+ //取出装置地址,开始处理地址+++
+ if(0x02 == pPortParam->m_au8RecvBuf[5])
+ {
+ //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4];
+ return;
+ }
+ cmdidx = pPortParam->m_au8RecvBuf[5];
+#if 0
+ aipnt = pPortParam->SameTypeDevIdx;
+ uDevAddr = serialport->m_au8RecvBuf[4];
+ if(0 == srdt.IsReadWireTem)
+ {
+ if(uDevAddr != pPortParam->devaddr)
+ return;
+ }
+#endif
+ fvalua = &fvalue;
+ datanum = pPortParam->m_au8RecvBuf[6];
+ if((0x08 != cmdidx) && (0x09 != cmdidx))
+ return;
+
+ for(i = 0, j=7; (im_au8RecvBuf[1]); i++, j+=5 )
+ {
+ if(0x08 == cmdidx)
+ fvalue = (pPortParam->m_au8RecvBuf[j+1]<<24)+(pPortParam->m_au8RecvBuf[j+2]<<16)
+ +(pPortParam->m_au8RecvBuf[j+3]<<8)+pPortParam->m_au8RecvBuf[j+4];
+ else
+ {
+ *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j+4];
+ *((u_char *)fvalua+1) = pPortParam->m_au8RecvBuf[j+3];
+ *((u_char *)fvalua+2) = pPortParam->m_au8RecvBuf[j+2];
+ *((u_char *)fvalua+3) = pPortParam->m_au8RecvBuf[j+1];
+ }
+ switch(pPortParam->m_au8RecvBuf[j])
+ {
+ case 1: /*温度*/
+ weatherpntmsg[0] = fvalue;
+ LOGE("温度:%0.3f ", fvalue);
+ break;
+ case 2: /*气压*/
+ weatherpntmsg[5] = fvalue;
+ LOGE("气压:%0.3f ", fvalue);
+ break;
+ case 3: /*湿度*/
+ weatherpntmsg[1] = fvalue;
+ LOGE("湿度:%0.3f ", fvalue);
+ break;
+ case 4: /*雨量*/
+ break;
+ case 5: /*日照*/
+ break;
+ case 6: /*风速*/
+ weatherpntmsg[2] = fvalue;
+ LOGE("风速:%0.3f ", fvalue);
+ break;
+ case 7: /*风向*/
+ weatherpntmsg[3] = fvalue;
+ LOGE("风向:%0.3f ", fvalue);
+ break;
+ case 8: /*拉力*/
+ case 9: /*倾角传感器X轴倾角*/
+ case 10: /*倾角传感器Y轴倾角*/
+ case 11: /*测温球导线温度*/
+ case 12: /*测温球内部温度*/
+ break;
+ case 13: /*测温球导线X轴倾角*/
+ break;
+ case 14: /*测温球导线Y轴倾角*/
+ break;
+ case 15: /*测温球导线电流*/
+ break;
+ case 16: /*测温球电池电压*/
+ break;
+ case 17: /*A相泄漏电流平均值;*/
+ break;
+ case 18: /*A相泄漏电流最大值;*/
+ break;
+ case 19: /*A相超过3mA的脉冲频次*/
+ break;
+ case 20: /*A相超过10mA的脉冲频次*/
+ break;
+ case 21: /*B相泄漏电流平均值;*/
+ break;
+ case 22: /*B相泄漏电流最大值;*/
+ break;
+ case 23: /*B相超过3mA的脉冲频次*/
+ break;
+ case 24: /*B相超过10mA的脉冲频次*/
+ case 25: /*C相泄漏电流平均值;*/
+ case 26: /*C相泄漏电流最大值;*/
+ case 27: /*C相超过3mA的脉冲频次*/
+ case 28: /*C相超过10mA的脉冲频次*/
+ break;
+ }
+ }
+}
+
+//***************************************************************
+//* 按照协议格式化接收数据 *
+//***************************************************************
+void RecvData(u_char *buf, int len)// 规约读数据处理
+{
+ int i, ictime;
+ //WORD crc, check;
+ SIO_PARAM_SERIAL_DEF *pPortParam;
+
+ pPortParam = &serialport;
+ ictime = (int)time(NULL);
+
+ if(pPortParam->m_iRecvLen == 0)
+ {
+ pPortParam->iRecvTime = ictime;
+ }
+ else
+ {
+ if((ictime-pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0))
+ pPortParam->iRecvTime = ictime;
+ else if(ictime - pPortParam->iRecvTime > 2)
+ {
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_iRevStatus = 0;
+ }
+ }
+
+ for(i=0; im_iRevStatus)
+ {
+ case 0: // 0x68
+ pPortParam->m_iRecvLen = 0;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 1: // len1
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus++;
+ break;
+ case 2: // len2
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen-2])
+ {
+ pPortParam->m_iRevStatus++;
+ pPortParam->m_iNeedRevLength = buf[i]+5;
+ }
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 3: // 0x68
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iNeedRevLength--;
+ if(0x68 == buf[i])
+ pPortParam->m_iRevStatus++;
+ else
+ pPortParam->m_iRevStatus = 18;
+ break;
+ case 4: // 正确接收数据
+ pPortParam->m_iNeedRevLength--;
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iNeedRevLength > 0)
+ break;
+ if(buf[i] != 0x16)
+ {
+ pPortParam->m_iRevStatus=18;
+ break;
+ }
+
+ //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE)
+ {
+ PortDataProcess();
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->RevCmdFlag = 1;
+ }
+ pPortParam->m_iRecvLen = 0;
+ break;
+ case 255:// 错误接收数据
+ default:
+ if(buf[i] == 0x68)
+ {
+ pPortParam->m_iRevStatus = 1;
+ pPortParam->m_iRecvLen = 1;
+ pPortParam->m_au8RecvBuf[0] = buf[i];
+ }
+ else if(buf[i] == 0x16)
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ pPortParam->m_iRevStatus = 0;
+ pPortParam->m_iRecvLen = 0;
+ }
+ else
+ {
+ pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
+ if(pPortParam->m_iRecvLen > 200)
+ {
+ pPortParam->m_iRecvLen = 0;
+ }
+ }
+ break;
+ }
+ }
+}
+
+//int inum =0;
+//int itimecnt=0;
+int weather_comm(SERIAL_PARAM weatherport)
+{
+ int fd = -1;
+ int len, i,ret, ictime, iruntime, isendtime, irecvtime, icnt=0;
+ unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16};
+ char recvbuf[256], szbuf[512];
+ //char serial_description[] = "/dev/ttyS0";
+
+#if 0
+ DIR *dir = opendir("/dev");
+ if (dir == NULL) {
+ LOGE("_test_ opendir");
+ return -1;
+ }
+
+ // 读取目录项
+ struct dirent *entry;
+ while ((entry = readdir(dir)) != NULL) {
+ // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头
+ if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
+ (strncmp(entry->d_name, "ttyS0", 5) == 0)) {
+ LOGE("_test_ Found serial port: %s\n", entry->d_name);
+ }
+ }
+
+ // 关闭目录
+ closedir(dir);
+#endif
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+
+ set12VEnable(true);
+ setCam3V3Enable(true);
+ setRS485Enable(true);
+
+ ictime = (int)time(NULL);
+ for(;;)
+ {
+ if(fd < 0)
+ {
+ fd = open(weatherport.pathname, O_RDWR | O_NDELAY);
+ //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY);
+ if(fd < 0)
+ {
+ LOGE("_test_ open serial error \n");
+ perror(weatherport.pathname);
+ return -1;
+ }
+
+ ret= set_port_attr (fd, weatherport.baudrate,weatherport.databit,weatherport.stopbit,weatherport.parity,0,0 );/*9600 8n1 */
+ if(ret < 0)
+ {
+ LOGE("_test_ set uart arrt faile \n");
+ return -1;
+ }
+ }
+
+ usleep(10000);
+ iruntime = (int)time(NULL);
+ if((iruntime - ictime > 120) || (iruntime - ictime < 0))
+ ictime = iruntime;
+ if(iruntime - ictime > 19)
+ {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "气象采样时间=%d,停止采样!", iruntime-ictime);
+ LOGE("%s", szbuf);
+ break;
+ }
+
+ if(1 == serialport.RevCmdFlag)
+ {
+ set485WriteMode();
+
+ len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
+ serialport.RevCmdFlag = 0;
+ isendtime = time(NULL);
+ if (len < 0) {
+ LOGE("write data error \n");
+ return -1;
+ } else {
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Send:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]);
+ }
+ LOGE("%s", szbuf);
+ //icnt = 0;
+ //inum++;
+ }
+ tcdrain(fd);
+ //usleep(50000);
+ }
+ else
+ {
+ irecvtime = time(NULL);
+ if((irecvtime-isendtime > 6) ||(irecvtime - isendtime < 0))
+ isendtime = irecvtime;
+ if (irecvtime-isendtime > 1)
+ {
+ LOGE("传感器超过%d秒未应答", irecvtime-isendtime);
+ serialport.RevCmdFlag = 1;
+ serialport.m_iRecvLen = 0;
+ serialport.m_iRevStatus = 0;
+ close(fd);
+ //set12VEnable(false);
+ //setCam3V3Enable(false);
+ //setRS485Enable(false);
+ fd = -1;
+ continue;
+ }
+ }
+ set485ReadMode();
+ memset(recvbuf, 0, sizeof(recvbuf));
+ len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */
+ if (len < 0) {
+ LOGE("serial read error \n");
+ continue;
+ }
+ if(0 == len)
+ {
+ //icnt++;
+ continue;
+ }
+
+ memset(szbuf, 0, sizeof(szbuf));
+ sprintf(szbuf, "Recv:");
+ for (i = 0; i < len; i++) {
+ sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]);
+ }
+ __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf);
+ RecvData((u_char*)recvbuf, len);
+ //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt);
+ icnt = 0;
+ //serialport.RevCmdFlag =1;
+ }
+
+ close(fd);
+ set12VEnable(false);
+ setCam3V3Enable(false);
+ setRS485Enable(false);
+
+ //exit(-1);
+ return(0);
+}
+
+int serial_port_comm()
+{
+ SERIAL_PARAM portparm;
+#if 1
+ memset(portparm.pathname, 0, sizeof(portparm.pathname));
+ sprintf(portparm.pathname, "/dev/ttyS0");
+ portparm.parity = 'N';
+ portparm.databit = 8;
+ portparm.baudrate = B9600;
+ memset(portparm.stopbit, 0, sizeof(portparm.stopbit));
+ sprintf(portparm.stopbit, "1");
+#endif
+ //itimecnt = (int)time(NULL);
+
+ for(;;)
+ weather_comm(portparm);
+ return 0;
+}
+#endif
+extern "C" JNIEXPORT jstring JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_stringFromJNI(
+ JNIEnv* env,
+ jobject /* this */) {
+ std::string hello = "Hello from C++";
+ return env->NewStringUTF(hello.c_str());
+}
+
+extern "C" JNIEXPORT jstring JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_testSpi(
+ JNIEnv* env,
+ jobject /*this*/, jint port) {
+ //testSpi();
+ SpiLIb a;
+ unsigned char newkey[32]={0xaf,0x0c,0xa9,0x40,0x1f,0xe6,0xee,0x0f,0x4c,
+ 0xfb,0xf7,0x17,0x71,0xde,0x61,0x59
+ ,0x0a,0x05,0x77,
+ 0xfa,0xe7,0xd1,0x8d,0x10,0x3a,0x79,0x23,0xf2,0xb3,
+ 0x6d,0xea,0x8e
+// ,0xe0,0x64,0xe7,0x5d,0x49,0x84,0xe4,
+// 0x5f,0xc9,0x07,0x03,0x52,0x33,0x79,0x87,0xd4,0x62,
+// 0x62,0xc0,0xcc,0xf0,0xd6,0x85,0x20,0x7f,0x7a,0xe8,
+// 0xc8,0xed,0x12,0xdb,0xdc
+ };
+ unsigned char outpub[32],outsign[64], *outen = new unsigned char [256];
+ unsigned char pucid[16]={0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
+ string b="C=CN,ST=jiangsu,L=nanjing,O=GDD,OU=nari,CN=test001";
+ //a.SM2keypair(0x00);
+ //a.SM3Hash(newkey,16, outpub);
+ //a.sm3hash_tosm2(newkey,16,outpub,newkey,pucid,16);
+ //a.SM2Sign(0x00,outpub,outsign);
+ //a.SM2VerifySign(0x00,outpub,outsign);
+ //if(i < wen, i++)
+ //lxy modify modify
+ //LOGE("_test_ setRS485Enable true");
+ //setRS485Enable(true);
+
+ //set12VEnable(true);
+ //serial_port_comm();
+ //GM_StartSerialComm();
+ testComm();
+ //GM_StartSerialCameraPhoto(1, 0);
+ //lxy modify modify
+ //LOGE("_test_ setRS485Enable false");
+ //setRS485Enable(false);
+ return env->NewStringUTF("");
+
+#if 0
+ DIR *dir = opendir("/dev");
+ if (dir == NULL) {
+ perror("opendir");
+ //return env->NewStringUTF("error");
+ //return -1;
+ }
+
+ // 读取目录项
+ struct dirent *entry;
+ while ((entry = readdir(dir)) != NULL) {
+ // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头
+ if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
+ (strncmp(entry->d_name, "ttyS0", 5) == 0)) {
+ printf("Found serial port: %s\n", entry->d_name);
+ }
+ }
+
+ // 关闭目录
+ closedir(dir);
+#endif
+ a.SM2cert(0x00,0x00,b,outen);
+ for (int i = 0; i < 32; i++) {
+ //sprintf(output, " %02x ", rxbuf[i]);
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "%02x", outen[i]);
+ }
+// a.SM2decoder(0x00,outen,outpub);
+//
+// for (int i = 0; i < 64; i++) {
+// //sprintf(output, " %02x ", rxbuf[i]);
+// __android_log_print(ANDROID_LOG_INFO, "SPi", "%02x", outpub[i]);
+// }
+
+ //a.SM3Hash(0x00,0x10,newkey);
+ //testVersion();
+
+ return env->NewStringUTF("End");
+
+ // NrsecSpiPort spi("/dev/mtkgpioctrl");
+ NrsecSpiPort spi("/dev/spidevSE");
+
+ // NrsecSpiPort spi("/dev/spidev0.0");
+
+ if (!spi.Open()) {
+ return env->NewStringUTF(spi.GetLog().c_str());
+ }
+
+ spi.GenKeyPair(0);
+
+ unsigned char header[] = { 0x00, 0x5b, 0x00, 0x00, 0x40 };
+
+ int bytesWriten = spi.Write(header, sizeof(header));
+ unsigned char buffer[1024] = { 0 };
+ int bytesRead = spi.Read(buffer, 1);
+ if (bytesRead > 0) {
+ int aa = 0;
+ } else {
+ int bb = 0;
+ }
+ int len = buffer[0];
+ bytesRead += spi.Read(&buffer[1], len);
+
+ spi.Close();
+
+ std::string result;
+ char buf[32] = { 0 };
+ for (int idx = 0; idx < 32; idx++)
+ {
+ sprintf(buf, "%X ", buffer[idx]);
+ result += buf;
+ }
+
+
+
+ return env->NewStringUTF(result.c_str());
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnOn(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnOff(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnLeft(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnRight(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnUp(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnDown(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_zoomIn(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_zoomOut(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_setSpeed(
+ JNIEnv* env,
+ jobject /*this*/, jint speed) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_setPreset(
+ JNIEnv* env,
+ jobject /*this*/, jint preset) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_gotoPreset(
+ JNIEnv* env,
+ jobject /*this*/, jint preset) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnOnWipers(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnOffWipers(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnOnLight(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_xinyingpower_testcomm_MainActivity_turnOffLight(
+ JNIEnv* env,
+ jobject /*this*/) {
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//// lxy add
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#if 0
+static speed_t getBaudrate(jint baudrate)
+{
+ switch(baudrate) {
+ case 0: return B0;
+ case 50: return B50;
+ case 75: return B75;
+ case 110: return B110;
+ case 134: return B134;
+ case 150: return B150;
+ case 200: return B200;
+ case 300: return B300;
+ case 600: return B600;
+ case 1200: return B1200;
+ case 1800: return B1800;
+ case 2400: return B2400;
+ case 4800: return B4800;
+ case 9600: return B9600;
+ case 19200: return B19200;
+ case 38400: return B38400;
+ case 57600: return B57600;
+ case 115200: return B115200;
+ case 230400: return B230400;
+ case 460800: return B460800;
+ case 500000: return B500000;
+ case 576000: return B576000;
+ case 921600: return B921600;
+ case 1000000: return B1000000;
+ case 1152000: return B1152000;
+ case 1500000: return B1500000;
+ case 2000000: return B2000000;
+ case 2500000: return B2500000;
+ case 3000000: return B3000000;
+ case 3500000: return B3500000;
+ case 4000000: return B4000000;
+ default: return -1;
+ }
+}
+char* jstring2str(JNIEnv* env, jstring jstr)
+{
+ char* rtn = NULL;
+ jclass clsstring = env->FindClass("java/lang/String");
+ jstring strencode = env->NewStringUTF("UTF-8");
+ jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
+ jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr,mid,strencode);
+ jsize alen = env->GetArrayLength(barr);
+ jbyte* ba = env->GetByteArrayElements(barr,JNI_FALSE);
+
+ if(alen > 0)
+ {
+ rtn = (char*)malloc(alen+1); //new char[alen+1];
+ memcpy(rtn,ba,alen);
+ rtn[alen] = 0;
+ }
+
+ env->ReleaseByteArrayElements(barr,ba,0);
+ return (char*)rtn;
+}
+
+
+int g_fd = -1;
+int serial_open(char *devPath, speed_t baudrate ) {
+ int ret = 0;
+ setRS485Enable(true);
+ int fd = open("/dev/ttyS0", O_RDWR |O_NOCTTY |O_NONBLOCK);
+ LOGE("_test_ serial_open fd=%d \n",fd);
+ if(fd < 0)
+ {
+ LOGE("_test_ open serial error \n");
+ return 0;
+ }
+ //ret= set_port_attr (fd, baudrate,8,"1",'N',150,0 );/*9600 8n1 */
+ ret= set_port_attr (fd, baudrate,8,"1",'N',150,0 );/*9600 8n1 */
+ if(ret < 0)
+ {
+ LOGE("_test_ set serial param fail \n");
+ return 0;
+ }
+ g_fd = fd;
+ return 1;
+}
+
+void serial_close()
+{
+ LOGE("_test_ serial_close fd=%d \n",g_fd);
+ if(g_fd != -1)
+ {
+ close(g_fd);
+ setRS485Enable(false);
+ }
+ g_fd = -1;
+}
+
+int serial_write(char *sendbuf, int length)
+{
+ int len = 0;
+ if(g_fd < 0)
+ return 0;
+ set485WriteMode();
+ len = write(g_fd, sendbuf, length);/* 向串囗发送字符串 */
+ LOGE("_test_ serial_write len=%d \n",len);
+ if (len < 0)
+ {
+ LOGE("_test_ write data error \n");
+ return 0;
+ }
+ return len;
+}
+
+int serial_read(char *readbuf,int length)
+{
+ int len = 0;
+ if(g_fd < 0)
+ return 0;
+ set485ReadMode();
+ memset(readbuf, 0, length);
+ len = read(g_fd, readbuf, length);/* 在串口读取字符串 */
+ LOGE("_test_ serial_read len=%d \n",len);
+ if (len < 0)
+ {
+ //LOGE("_test_ read error \n");
+ return 0;
+ }
+ return len;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_com_xinyingpower_testcomm_MainActivity_openSerial
+(JNIEnv* env, jobject, jstring dev, jint baudrate) {
+ char *devPath = jstring2str(env, dev);
+ LOGE("_test open serial path=%s, baudrate=%d\n", devPath, baudrate);
+ speed_t speed = getBaudrate(baudrate);
+ int res = serial_open(devPath, speed);
+ return res == 1 ? JNI_TRUE: JNI_FALSE;
+}
+
+extern "C" JNIEXPORT void JNICALL Java_com_xinyingpower_testcomm_MainActivity_closeSerial
+ (JNIEnv* env, jobject) {
+ serial_close();
+}
+
+extern "C" JNIEXPORT jint JNICALL Java_com_xinyingpower_testcomm_MainActivity_writeSerial
+ (JNIEnv *env, jobject , jbyteArray jstr) {
+ jsize len = env->GetArrayLength(jstr);
+ if (len <= 0)
+ return 0;
+ jbyte *jdata = env->GetByteArrayElements(jstr, 0);
+ int res = serial_write((char*)jdata, len);
+ env->ReleaseByteArrayElements(jstr, jdata, 0);
+ return res;
+}
+
+extern "C" JNIEXPORT jint JNICALL Java_com_xinyingpower_testcomm_MainActivity_readSerial
+ (JNIEnv *env, jobject, jbyteArray out)
+{
+ jsize outlen = env->GetArrayLength(out);
+ //LOGE("_test readSerial outlen=%d\n", outlen);
+ if(outlen <= 0)
+ return 0;
+ jbyte* outData = env->GetByteArrayElements(out, 0);
+ char* outbuf = (char*)outData;
+ int res = serial_read(outbuf, outlen);
+ //LOGE("_test serial_read res=%d\n", res);
+ env->ReleaseByteArrayElements(out, outData, 0);
+ return res;
+}
+#endif
\ No newline at end of file
diff --git a/app/src/main/cpp/serialComm.cpp b/app/src/main/cpp/serialComm.cpp
new file mode 100644
index 0000000..b300d1c
--- /dev/null
+++ b/app/src/main/cpp/serialComm.cpp
@@ -0,0 +1,116 @@
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "GPIOControl.h"
+#include "serialComm.h"
+
+
+static void set_baudrate (struct termios *opt, unsigned int baudrate)
+{
+ cfsetispeed(opt, baudrate);
+ cfsetospeed(opt, baudrate);
+}
+
+static void set_data_bit (struct termios *opt, unsigned int databit)
+{
+ opt->c_cflag &= ~CSIZE;
+ switch (databit)
+ {
+ case 8:
+ opt->c_cflag |= CS8;
+ break;
+ case 7:
+ opt->c_cflag |= CS7;
+ break;
+ case 6:
+ opt->c_cflag |= CS6;
+ break;
+ case 5:
+ opt->c_cflag |= CS5;
+ break;
+ default:
+ opt->c_cflag |= CS8;
+ break;
+ }
+}
+
+static void set_parity (struct termios *opt, char parity)
+{
+ switch (parity)
+ {
+ case'N':/* 无校验 */
+ case 'n':
+ opt->c_cflag &= ~PARENB;
+ break;
+ case'E':/*偶校验*/
+ case 'e':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag &= ~PARODD;
+ break;
+ case'O':/* 奇校验 */
+ case 'o':
+ opt->c_cflag |= PARENB;
+ opt->c_cflag |= ~PARODD;
+ break;
+ default: /*其它选择为无校验 */
+ opt->c_cflag &= ~PARENB;
+ break;
+ }
+}
+
+static void set_stopbit (struct termios *opt, const int stopbit)
+{
+ switch (stopbit)
+ {
+ case 10:
+ opt->c_cflag &= ~CSTOPB;/*1 位停止位 t */
+ break;
+ case 15:
+ opt->c_cflag &= ~CSTOPB;/*1.5 位停止位 */
+ break;
+ case 20:
+ opt->c_cflag |= CSTOPB; /*2 位停止位 */
+ break;
+ default:
+ opt->c_cflag &= ~CSTOPB; /*1 位停止位 */
+ break;
+ }
+}
+
+int set_port_attr (int fd, unsigned int baudrate, int databit, const int stopbit, char parity, int vtime, int vmin )
+{
+ struct termios opt;
+ tcgetattr(fd, &opt);
+ set_baudrate(&opt, baudrate);
+ //opt.c_cflag |= CLOCAL|CREAD; /*|CRTSCTS */
+ opt.c_lflag &= ~(ICANON | ECHO |ECHOE |ISIG);
+ set_data_bit(&opt, databit);
+ set_parity(&opt, parity);
+ set_stopbit(&opt, stopbit);
+ opt.c_iflag &=~(INLCR|ICRNL);
+ opt.c_iflag &=~(IXON);/* 流控*/
+ opt.c_oflag = 0;
+ //opt.c_lflag |= 0;
+ opt.c_oflag &= ~OPOST;
+ opt.c_cc[VTIME] = vtime;
+ opt.c_cc[VMIN] = vmin;
+ tcflush (fd, TCIFLUSH);
+ return (tcsetattr (fd, TCSANOW, &opt));
+}
+
+
+
+
diff --git a/app/src/main/cpp/serialComm.h b/app/src/main/cpp/serialComm.h
new file mode 100644
index 0000000..a882522
--- /dev/null
+++ b/app/src/main/cpp/serialComm.h
@@ -0,0 +1,19 @@
+//
+// Created by hyz on 2024/6/5.
+//
+
+#ifndef SERIAL_COMM_BASE89656_H
+#define SERIAL_COMM_BASE89656_H
+
+#include
+#include "GPIOControl.h"
+
+#define MAX_STRING_LEN 32
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+
+//#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "serial_port_comm", fmt, ##args)
+
+int set_port_attr (int fd, unsigned int baudrate, int databit, const int stopbit, char parity, int vtime, int vmin );
+
+#endif //SERIAL_COMM_BASE89656_H
diff --git a/app/src/main/cpp/spi-test-random.cpp b/app/src/main/cpp/spi-test-random.cpp
new file mode 100644
index 0000000..e519010
--- /dev/null
+++ b/app/src/main/cpp/spi-test-random.cpp
@@ -0,0 +1,426 @@
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#define CMD_HEAD_SIZE 5
+typedef unsigned char u8;
+
+#define RE_SUC 0x01
+#define RE_ERROR 0x00
+
+const unsigned char crc7_table[256] = {
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
+ 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
+ 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
+ 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
+ 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
+ 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
+ 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
+ 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
+ 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
+ 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
+ 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
+ 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
+ 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
+ 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
+ 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
+};
+
+const unsigned char EK_CMD[5]={0x80,0xd4,0x01,0x00,0x10};
+const unsigned char AK_CMD[5]={0x80,0xd4,0x02,0x00,0x10};
+const unsigned char IV_CMD[5]={0x80,0xd4,0x04,0x00,0x10};
+volatile unsigned char SM1encrpt_CMD[5]={0xa0,0xe0,0x80,0xff,0xff};
+volatile unsigned char SM1decoder_CMD[5]={0xa0,0xe0,0x81,0xff,0xff};
+volatile unsigned char SM2Keypair_CMD[5]={0x80,0xb2,0x00,0xff,0x00};
+volatile unsigned char SM2OutPub_CMD[5]={0x80,0xb8,0x01,0xff,0x40};
+volatile unsigned char SM2OutPri_CMD[5]={0x80,0xb8,0x02,0xff,0x20};
+volatile unsigned char SM2InPub_CMD[5]={0x80,0xba,0x01,0xff,0x40};
+volatile unsigned char SM2InPri_CMD[5]={0x80,0xba,0x02,0xff,0x20};
+volatile unsigned char SM3Hash_CMD[5]={0x80,0xb5,0x00,0xff,0xff};
+volatile unsigned char SM2Sign_CMD[5]={0x80,0xb4,0x00,0xff,0x20};
+volatile unsigned char SM2VerifySign_CMD[5]={0x80,0xb6,0x00,0xff,0x60};
+volatile unsigned char SM2encrypt_CMD[5]={0x80,0xb3,0x01,0xff,0x20};
+volatile unsigned char SM2decoder_CMD[5]={0x80,0xb3,0x81,0xff,0x80};
+volatile unsigned char SM2cert_CMD[5]={0x80,0xb7,0xff,0xff,0xff};
+volatile unsigned char Random_CMD[5]={0x00,0x84,0x00,0x00,0xff};
+const unsigned char Version_CMD[5]={0x00,0x5b,0x00,0x00,0x40};
+const unsigned char Indentify_CMD[5]={0x80,0xb3,0x01,0x04,0x20};
+
+int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int bytes)
+{
+ struct spi_ioc_transfer xfer[2];
+ int status;
+
+ memset(xfer, 0, sizeof(xfer));
+
+ xfer[0].tx_buf = (__u64)txbuf;
+ xfer[0].rx_buf = (__u64)rxbuf;
+ xfer[0].len = bytes;
+
+ status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);
+ if (status < 0)
+ {
+ perror("SPI_IOC_MESSAGE");
+ return -1;
+ }
+
+ return status;
+
+}
+
+void spi_master_init(const char *name, int fd)
+{
+ __u8 mode = 3;
+ __u8 lsb, bits;
+ //__u32 speed = 30000000;
+ __u32 speed = 2000000;
+ //__u32 speed = 2000000;
+ //__u32 speed = 33000000;
+
+ // SPI_IOC_WR_MODE
+
+ ioctl(fd, SPI_IOC_WR_MODE, &mode);
+ ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+
+ if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0)
+ {
+ perror("SPI rd_mode");
+ return;
+ }
+
+ if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
+ {
+ perror("SPI rd_lsb_fist");
+ return;
+ }
+
+ if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
+ {
+ perror("SPI rd bits_per_word");
+ return;
+ }
+
+ if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
+ {
+ perror("SPI rd max_speed_hz");
+ return;
+ }
+
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "%s: spi mode %d, %d bits %sper word, %d Hz max\n", name, mode, bits, lsb ? "(lsb first) " : "", speed);
+ //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
+ // name, mode, bits, lsb ? "(lsb first) " : "", speed);
+}
+
+unsigned char get_crc7(const unsigned char *buff, int len)
+{
+ unsigned char crc7_accum = 0;
+ int i;
+
+ for (i=0; i < len; i++) {
+ crc7_accum =
+ crc7_table[(crc7_accum << 1) ^ buff[i]];
+ }
+ return crc7_accum;
+}
+
+int delay(int x)
+{
+ // while (--x);
+ // std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ usleep(50000);
+ return 0;
+}
+
+void delay_us(int x)
+{
+ usleep(x);
+};
+
+void SendCmdHeader(int fd,u8 *cmd, u8 *rxbuf)
+{
+ int i=0;
+ int retval;
+
+#if defined (CONFIG_ATMEL_SPI_DEBUG)
+ printf("tx %1d bytes: ", CMD_HEAD_SIZE);
+ for (i = 0; i < CMD_HEAD_SIZE; i++)
+ {
+ printf(" %02x", cmd[i]);
+ }
+ printf("\n");
+#endif
+
+ /* send five command header */
+ for (i=0; i< CMD_HEAD_SIZE; i++)
+ {
+ retval = spi_transfer(fd, cmd+i, rxbuf+i, 1);
+ __android_log_print(ANDROID_LOG_INFO, "SPiCMD", "cmd[%d]=%x,rxbuf[%d]=%x",i,*(cmd+i),i, *(rxbuf+i));
+ delay(20);
+ }
+
+ cmd[0]=0xaa; //for response
+
+}
+
+void RcvINS(int fd, u8 *txbuf, u8 *buf, u8 ins)
+{
+ int retval;
+ int cnt = 1000;
+ int count=0;
+ /* receive ins */
+INS:
+ txbuf[0] = 0xaa;
+ delay(20);
+ while(cnt--)
+ {
+ retval = spi_transfer(fd, txbuf, buf, 1);
+ __android_log_print(ANDROID_LOG_INFO, "SPiINS", "txbuf=%x,buf=%x", *txbuf,*buf);
+ if(*buf == ins)
+ {
+ return;
+ break;
+ }
+ else
+ goto INS;
+ }
+}
+
+void RcvLEN(int fd, u8 *txbuf, u8 *buf, u8 len)
+{
+
+ int retval;
+ /* receive length */
+LEN:
+ retval = spi_transfer(fd, txbuf, buf, 1);
+ __android_log_print(ANDROID_LOG_INFO, "SPiLEN", "txbuf=%x,rxbuf=%hhu", *txbuf,*buf);
+}
+
+//Rcvdata
+void RcvData(int fd, u8 *txbuf, u8 *buf)
+{
+ int i;
+ int retval;
+
+ /* receive data and crc */
+ for(i=0; i<*(buf-1); i++)
+ {
+
+ retval = spi_transfer(fd, txbuf, buf+i, 1);
+ __android_log_print(ANDROID_LOG_INFO, "SPiDATA", "data[%d]=%x",i, *(buf+i));
+ }
+}
+
+
+//RcvSW
+void RcvSW(int fd, u8 *txbuf, u8 *buf, u8 sw)
+{
+ int i;
+ int retval;
+
+SW90:
+ /* receive state word */
+ delay(20);
+ while(1)
+ {
+ retval = spi_transfer(fd, txbuf, buf, 1);
+ if(*buf != sw)
+ {
+ goto SW90;
+ }
+ break;
+ }
+ retval = spi_transfer(fd, txbuf, buf+1, 1);
+}
+
+
+int testSpi()
+{
+ int i;
+ int cnt;
+ unsigned char txbuf[256];
+ unsigned char rxbuf[256];
+
+ int retval;
+ int msglen;
+ int fd;
+ const char *devname = "/dev/spidevSE";
+
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0");
+ // devname = "/dev/spidevSE";
+
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ printf("tx %1d bytes: ", msglen);
+
+CMD_RESEND:
+ txbuf[0] = 0x00;
+ txbuf[1] = 0x84;
+ txbuf[2] = 0x00;
+ txbuf[3] = 0x00;
+ txbuf[4] = 0x08;
+
+ SendCmdHeader(fd, txbuf, rxbuf);
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]); // 指令
+
+ RcvLEN(fd, txbuf,rxbuf+1, txbuf[4]+1); //长度 多加一个字节的 CRC
+
+ RcvData(fd, txbuf, rxbuf+2);
+
+ RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90);
+
+ //计算接收到数据的CRC
+ if(get_crc7(rxbuf+2, rxbuf[1]-1) != rxbuf[rxbuf[1]+1])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if(cnt<3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ printf("ERROR\n");
+ }
+ }
+
+ printf("rx %1d bytes: ", rxbuf[1]+4);
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ close(fd);
+
+ std::string result = "Random: ";
+ char output[16] = { 0 };
+ for (i = 0; i < rxbuf[1]+4; i++) {
+ sprintf(output, " %02x ", rxbuf[i]);
+ result += output;
+ }
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "%s", result.c_str());
+ // printf("\n");
+
+ return 0;
+}
+
+int testVersion()
+{
+ int i;
+ int cnt;
+ unsigned char txbuf[256];
+ unsigned char rxbuf[256];
+
+ int retval;
+ int msglen;
+ int fd;
+ //const char *devname = "/dev/spidevSE";
+ //const char *devname = "/dev/spidev0.0";
+ const char *devname = "/dev/mtkgpioctrl";
+
+ // NrsecSpiPort spi("/dev/spidevSE");
+ //
+ // // NrsecSpiPort spi("/dev/spidev0.0");
+
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+ spi_master_init(devname, fd);
+
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+
+ CMD_RESEND:
+
+ memcpy(txbuf, Version_CMD, sizeof(Version_CMD));
+
+ SendCmdHeader(fd, txbuf, rxbuf);
+
+ RcvINS(fd,txbuf,rxbuf,txbuf[1]); // 指令
+
+ RcvLEN(fd,txbuf,rxbuf+1, txbuf[4]); //长度 多加一个字节的 CRC
+
+ RcvData(fd, txbuf, rxbuf+2);
+
+ RcvSW(fd, txbuf, rxbuf+2+rxbuf[1], 0x90);
+
+ //计算接收到数据的CRC
+ if(get_crc7(rxbuf+2, rxbuf[1]-1) != rxbuf[rxbuf[1]+1])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if(cnt<3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ printf("ERROR\n");
+ }
+ }
+
+ //printf("rx %1d bytes: ", rxbuf[1]+4);
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ std::string result = "Version: ";
+ char output[16] = { 0 };
+ for (i = 0; i < rxbuf[1]+4; i++) {
+ sprintf(output, " %c ", rxbuf[i]);
+ result += output;
+ }
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "%s", result.c_str());
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf);
+ // printf("\n");
+
+ close(fd);
+ return 0;
+}
+
+
diff --git a/app/src/main/cpp/test b/app/src/main/cpp/test
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java b/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java
new file mode 100644
index 0000000..a39cecd
--- /dev/null
+++ b/app/src/main/java/com/xinyingpower/testcomm/MainActivity.java
@@ -0,0 +1,149 @@
+package com.xinyingpower.testcomm;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.TextView;
+
+import com.xinyingpower.testcomm.databinding.ActivityMainBinding;
+
+public class MainActivity extends AppCompatActivity {
+
+ // Used to load the 'testcomm' library on application startup.
+ static {
+ System.loadLibrary("testcomm");
+ }
+
+ private ActivityMainBinding binding;
+
+ View.OnClickListener onButtonClicked = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ int viewId = view.getId();
+ switch (viewId) {
+ case R.id.turnOn:
+ turnOn();
+ break;
+ case R.id.turnOff:
+ turnOff();
+ break;
+ case R.id.turnLeft:
+ turnLeft();
+ break;
+ case R.id.turnRight:
+ turnRight();
+ break;
+ case R.id.turnUp:
+ turnUp();
+ break;
+ case R.id.turnDown:
+ turnDown();
+ break;
+ case R.id.zoomIn:
+ zoomIn();
+ break;
+ case R.id.zoomOut:
+ zoomOut();
+ break;
+ case R.id.turnOnWipers:
+ turnOnWipers();
+ break;
+ case R.id.turnOffWipers:
+ turnOffWipers();
+ break;
+ case R.id.turnOnLight:
+ turnOnLight();
+ break;
+ case R.id.turnOffLight:
+ turnOffLight();
+ break;
+ case R.id.setSpeed:
+ {
+ int speed = 0;
+ try {
+ speed = Integer.parseInt(binding.speed.getText().toString());
+ } catch (Exception ex) {
+
+ }
+ setSpeed(speed);
+ }
+ break;
+ case R.id.setPreset:
+ case R.id.gotoPreset:
+ {
+ int preset = 0xFF;
+ try {
+ preset = Integer.parseInt(binding.preset.getText().toString());
+ } catch (Exception ex) {
+
+ }
+ if (viewId == R.id.setPreset) {
+ setPreset(preset);
+ } else {
+ gotoPreset(preset);
+ }
+ }
+ break;
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ binding = ActivityMainBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ binding.btnSpi.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ String s = binding.edtPort.getText().toString();
+// Integer integer = Integer.valueOf(s);
+ String str = testSpi(0);
+ }
+ });
+
+ Handler handler = new Handler();
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ binding.btnSpi.performClick();
+ }
+ };
+ handler.postDelayed(runnable, 1000);
+ }
+
+
+ /**
+ * A native method that is implemented by the 'testcomm' native library,
+ * which is packaged with this application.
+ */
+ public native String stringFromJNI();
+
+ public native String testSpi(int port);
+
+ public native void turnLeft();
+ public native void turnRight();
+ public native void turnUp();
+ public native void turnDown();
+
+ public native void turnOn();
+ public native void turnOff();
+
+ public native void zoomIn(); // 拉近
+ public native void zoomOut(); //
+
+ public native void setSpeed(int speed);
+ public native void setPreset(int preset);
+ public native void gotoPreset(int preset);
+
+ public native void turnOnWipers();
+ public native void turnOffWipers();
+
+ public native void turnOffLight();
+ public native void turnOnLight();
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..d87417f
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..48eb05a
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c69dab8
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ TestComm
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..3bc189d
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/xinyingpower/testcomm/ExampleUnitTest.java b/app/src/test/java/com/xinyingpower/testcomm/ExampleUnitTest.java
new file mode 100644
index 0000000..b70d146
--- /dev/null
+++ b/app/src/test/java/com/xinyingpower/testcomm/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.xinyingpower.testcomm;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..5ae9a7b
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,9 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '7.2.2' apply false
+ id 'com.android.library' version '7.2.2' apply false
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..dab7c28
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f65e217
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+#Tue Apr 02 12:39:24 CST 2024
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.3.3-bin.zip
+
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..21db480
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,22 @@
+pluginManagement {
+ repositories {
+ maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
+ maven { url 'https://maven.aliyun.com/repository/google' }
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ maven { url 'https://maven.aliyun.com/repository/public' }
+ maven { url 'https://maven.aliyun.com/repository/jcenter' }
+ maven { url 'https://maven.aliyun.com/repository/central' }
+ maven { url 'https://maven.aliyun.com/repository/google' }
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "TestComm"
+include ':app'