Compare commits

..

1 Commits
main ... serial

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

@ -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'
}

@ -1,4 +1,4 @@
package com.xypower.mpres;
package com.xinyingpower.testcomm;
import android.content.Context;
@ -21,6 +21,6 @@ public class ExampleInstrumentedTest {
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.xypower.mpres", appContext.getPackageName());
assertEquals("com.xinyingpower.testcomm", appContext.getPackageName());
}
}

@ -1,20 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="com.xypower.mp"
tools:ignore="Deprecated" >
package="com.xinyingpower.testcomm">
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MicroPhoto">
android:theme="@style/Theme.TestComm"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="landscape" >
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

@ -16,6 +16,7 @@
#include <time.h>
#include "GPIOControl.h"
#include "WeatherComm.h"
#include <sys/time.h>
SIO_PARAM_SERIAL_DEF serialport;
float weatherpntmsg[10];
@ -112,6 +113,42 @@ int set_port_attr (int fd, int baudrate, int databit, const char *stopbit, char
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, &param);
// 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);
}
/*********************************************************************************
* *
**********************************************************************************/
@ -329,12 +366,22 @@ static void RecvData(u_char *buf, int len)// 规约读数据处理
}
}
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, ictime, iruntime, isendtime, irecvtime, icnt=0;
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";
@ -366,8 +413,9 @@ static int weather_comm(SERIAL_PARAM weatherport)
set12VEnable(true);
setCam3V3Enable(true);
setRS485Enable(true);
ictime = (int)time(NULL);
sleep(2);
//ictime = (int)time(NULL);
ictime = get_msec();
for(;;)
{
if(fd < 0)
@ -390,13 +438,14 @@ static int weather_comm(SERIAL_PARAM weatherport)
}
usleep(10000);
iruntime = (int)time(NULL);
if((iruntime - ictime > 120) || (iruntime - ictime < 0))
//iruntime = (int)time(NULL);
iruntime = get_msec();
if((iruntime - ictime > 120000) || (iruntime - ictime < 0))
ictime = iruntime;
if(iruntime - ictime > 19)
if(iruntime - ictime > 20000)
{
memset(szbuf, 0, sizeof(szbuf));
sprintf(szbuf, "气象采样时间=%d,停止采样!", iruntime-ictime);
sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime-ictime)/1000.0);
LOGE("%s", szbuf);
break;
}
@ -407,7 +456,9 @@ static int weather_comm(SERIAL_PARAM weatherport)
len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
serialport.RevCmdFlag = 0;
isendtime = time(NULL);
LOGE("发送命令时间差%ld毫秒", get_msec()-isendtime);
//isendtime = time(NULL);
isendtime = get_msec();
if (len < 0) {
LOGE("write data error \n");
return -1;
@ -426,12 +477,13 @@ static int weather_comm(SERIAL_PARAM weatherport)
}
else
{
irecvtime = time(NULL);
if((irecvtime-isendtime > 6) ||(irecvtime - isendtime < 0))
//irecvtime = time(NULL);
irecvtime = get_msec();
if((irecvtime-isendtime > 6000) ||(irecvtime - isendtime < 0))
isendtime = irecvtime;
if (irecvtime-isendtime > 1)
if (irecvtime-isendtime > 300)
{
LOGE("传感器超过%d秒未应答", irecvtime-isendtime);
LOGE("传感器超过%ld秒未应答", irecvtime-isendtime);
serialport.RevCmdFlag = 1;
serialport.m_iRecvLen = 0;
serialport.m_iRevStatus = 0;
@ -480,6 +532,14 @@ static int weather_comm(SERIAL_PARAM weatherport)
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");
@ -491,7 +551,7 @@ int serial_port_comm()
#endif
//itimecnt = (int)time(NULL);
for(;;)
//for(;;)
weather_comm(portparm);
return 0;
}

@ -8,6 +8,10 @@
#include <string>
#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)
// 串口参数
@ -30,6 +34,14 @@ typedef struct
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();

@ -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})

@ -0,0 +1,144 @@
//
// Created by Matthew on 2023/12/27.
//
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include "GPIOControl.h"
#ifdef _DEBUG
#include <AndroidHelper.h>
#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, &param);
// 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, &param);
#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, &param);
// 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, &param);
// 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, &param);
// 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, &param);
// 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 "";
}

@ -0,0 +1,178 @@
//
// Created by Matthew on 2023/12/27.
//
#ifndef MICROPHOTO_GPIOCONTROL_H
#define MICROPHOTO_GPIOCONTROL_H
#include <string>
#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
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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,467 @@
//
// Created by hyz on 2024/6/5.
//
#ifndef WEATHERCOMM_H
#define WEATHERCOMM_H
#include <string>
#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 0 /* 调试使用*/
#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

@ -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 <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <jni.h>
#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);
}

@ -0,0 +1,18 @@
#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__
#include <string>
class SerialPort
{
public:
bool Open(std::string path, int, int);
bool Close();
protected:
int m_fd;
};
#endif // __SERIALPORT_H__

File diff suppressed because it is too large Load Diff

@ -0,0 +1,123 @@
#ifndef TESTCOMM_SPILIB_H
#define TESTCOMM_SPILIB_H
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <string>
#include <thread>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
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

@ -0,0 +1,62 @@
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <android/log.h>
#include <string>
#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;
}

@ -0,0 +1,30 @@
#ifndef _SPIPORT_H_
#define _SPIPORT_H_
#include <string>
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

@ -0,0 +1,595 @@
#include <jni.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include "GPIOControl.h"
#include "WeatherComm.h"
#include <sys/time.h>
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, &param);
// 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; (i<datanum) && (j<6+pPortParam->m_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; i<len; i++)
{
switch(pPortParam->m_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;
}

@ -0,0 +1,51 @@
//
// Created by hyz on 2024/6/5.
//
#ifndef WEATHERCOMM_H
#define WEATHERCOMM_H
#include <string>
#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

@ -0,0 +1,919 @@
#include <jni.h>
#include <string>
#include "SpiPort.h"
#include "SpiLib.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#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, &param);
// 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; (i<datanum) && (j<6+pPortParam->m_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; i<len; i++)
{
switch(pPortParam->m_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());
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// 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

@ -15,7 +15,7 @@
#include <termios.h>
#include <time.h>
#include "GPIOControl.h"
#include "SerialComm.h"
#include "serialComm.h"
static void set_baudrate (struct termios *opt, unsigned int baudrate)
@ -51,16 +51,16 @@ static void set_parity (struct termios *opt, char parity)
{
switch (parity)
{
case 'N':/* 无校验 */
case'N':/* 无校验 */
case 'n':
opt->c_cflag &= ~PARENB;
break;
case 'E':/*偶校验*/
case'E':/*偶校验*/
case 'e':
opt->c_cflag |= PARENB;
opt->c_cflag &= ~PARODD;
break;
case 'O':/* 奇校验 */
case'O':/* 奇校验 */
case 'o':
opt->c_cflag |= PARENB;
opt->c_cflag |= ~PARODD;

@ -0,0 +1,426 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <string>
#include <thread>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#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;
}

@ -0,0 +1,61 @@
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;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Example of a call to a native method
TextView tv = binding.sampleText;
// tv.setText(stringFromJNI());
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);
binding.sampleText.setText(s);
}
});
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);
}

@ -2,12 +2,12 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/sample_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
@ -16,4 +16,22 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnSpi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SPI"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<EditText
android:id="@+id/edtPort"
android:text=""
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnSpi"
android:layout_width="100dp"
android:layout_height="wrap_content">
</EditText>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.TestComm" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

@ -0,0 +1,3 @@
<resources>
<string name="app_name">TestComm</string>
</resources>

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.TestComm" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

@ -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
}

@ -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

Binary file not shown.

@ -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

185
TestComm/gradlew vendored

@ -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" "$@"

@ -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

@ -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'

@ -4,8 +4,8 @@ plugins {
// 10,00,000 major-minor-build
def AppMajorVersion = 1
def AppMinorVersion = 3
def AppBuildNumber = 196
def AppMinorVersion = 0
def AppBuildNumber = 148
def AppVersionName = AppMajorVersion + "." + AppMinorVersion + "." + AppBuildNumber
def AppVersionCode = AppMajorVersion * 100000 + AppMinorVersion * 1000 + AppBuildNumber
@ -26,7 +26,7 @@ android {
applicationId "com.xypower.mpapp"
minSdk COMPILE_MIN_SDK_VERSION as int
//noinspection ExpiredTargetSdkVersion
targetSdk TARGET_SDK_VERSION as int
targetSdk 28
versionCode AppVersionCode
versionName AppVersionName
@ -36,11 +36,11 @@ android {
externalNativeBuild {
cmake {
// cppFlags '-std=c++17 -frtti -fexceptions -Wno-error=format-security'
cppFlags '-std=c++17 -fexceptions -Wno-error=format-security -fopenmp'
cppFlags '-std=c++17 -fexceptions -Wno-error=format-security'
// cppFlags '-std=c++17 -Wno-error=format-security'
// arguments "-DANDROID_STL=c++_shared"
arguments "-DNCNN_DISABLE_EXCEPTION=OFF", "-DTERM_CORE_ROOT=" + coreroot, "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni", "-DHDRPLUS_ROOT=" + hdrplusroot, "-DNCNN_ROOT=" + ncnnroot, "-DHALIDE_ROOT=" + halideroot
abiFilters 'arm64-v8a', 'armeabi-v7a'
arguments "-DNCNN_DISABLE_EXCEPTION=OFF", "-DTERM_CORE_ROOT=" + coreroot, "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni", "-DASIO_ROOT=" + asioroot, "-DEVPP_ROOT=" + evpproot, "-DNCNN_ROOT=" + ncnnroot
abiFilters 'arm64-v8a'
// setAbiFilters(['arm64-v8a'])
}
}
@ -52,7 +52,6 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
jniDebuggable true
testCoverageEnabled false
}
@ -75,30 +74,14 @@ android {
}
}
splits {
boolean isReleaseTask = gradle.startParameter.taskNames.any { it.contains("Release") }
// enabled on release build
abi {
enable isReleaseTask
reset()
include "armeabi-v7a", "arm64-v8a"
// include "arm64-v8a"
universalApk false
}
}
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
if (outputFileName.endsWith('.apk')) {
def buildTypeFlag = "dbg"
def prevFileName = "mpapp"
if(variant.buildType.name.equals('release')) {
buildTypeFlag = "rel"
}
def abi = output.getFilter(com.android.build.OutputFile.ABI)
if (abi == null) abi = "all"
if (abi.contains("v7a")) prevFileName = "N938"
def fileName = "${prevFileName}_v${defaultConfig.versionName}_${buildTypeFlag}_${new Date(System.currentTimeMillis()).format("yyyyMMdd")}.apk"
def fileName = "mpapp_v${defaultConfig.versionName}_${buildTypeFlag}_${new Date(System.currentTimeMillis()).format("yyyyMMdd")}.apk"
outputFileName = fileName
}
}
@ -114,22 +97,15 @@ android {
exclude 'META-INF/INDEX.LIST'
exclude 'META-INF/io.netty.versions.properties'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE-notice.md'
exclude 'META-INF/LICENSE.md'
jniLibs {
useLegacyPackaging true
}
}
}
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
// implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.0'
// implementation "androidx.core:core:1.10.0" // 使
implementation 'androidx.fragment:fragment:1.3.6'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.material:material:1.8.0'
implementation project(path: ':common')
@ -143,13 +119,7 @@ dependencies {
// implementation 'com.tencent:mmkv-static:1.3.0'
// implementation project(path: ':opencv')
implementation files('libs/devapi.aar')
// debugImplementation files('libs/rtmp-client-debug.aar')
implementation files('libs/android-openGL-canvas-1.5.4.0.aar')
implementation files('libs/rtmp-client.aar')
api project(':gpuv')
implementation project(':stream')
implementation 'dev.mobile:dadb:1.2.7'
implementation project(':gpuv')
// implementation group: 'io.netty', name: 'netty-all', version: '4.1.96.Final'
// implementation 'io.netty:netty-all:4.1.23.Final'

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="com.xypower.mp"
tools:ignore="Deprecated">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
@ -12,10 +10,9 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
@ -57,8 +54,6 @@
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-permission
android:name="android.permission.DEVICE_POWER"
tools:ignore="ProtectedPermissions" />
@ -67,47 +62,17 @@
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
tools:ignore="ProtectedPermissions" /> <!-- WiFi AP startTethering -->
<uses-permission
android:name="android.permission.TETHER_PRIVILEGED"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL"
tools:ignore="ProtectedPermissions" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="com.mediatek.camera.feature.mfnr" />
<uses-permission android:name="android.hardware.usb.accessory" />
<uses-feature android:name="android.hardware.usb.host" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<queries>
<provider
android:name=".BridgeProvider"
android:authorities="com.xypower.mpapp.provider"
android:enabled="true"
android:exported="false"
android:grantUriPermissions="true" />
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
<intent>
<action android:name="android.media.action.STILL_IMAGE_CAMERA" />
</intent>
<intent>
<action android:name="android.intent.action.TIME_CHANGED" />
</intent>
<package android:name="com.xypower.mplive" />
</queries>
<application
android:dataExtractionRules="@xml/data_extraction_rules"
android:extractNativeLibs="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@ -115,32 +80,12 @@
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"
android:theme="@style/Theme.MicroPhoto"
tools:targetApi="28">
<activity
android:name=".LogActivity"
android:exported="false"
android:screenOrientation="landscape" />
<activity
android:name=".video.RawActivity"
android:exported="false"
android:screenOrientation="landscape" />
<activity
android:name=".StreamActivity"
android:exported="false"
android:screenOrientation="landscape" />
<provider
android:name=".BridgeProvider"
android:authorities="com.xypower.mpapp.provider"
android:enabled="true"
android:exported="true"
android:grantUriPermissions="true" />
android:extractNativeLibs="true"
tools:targetApi="28">
<activity
android:name=".BridgeActivity"
android:exported="true"
android:process=":bridge_proc"
android:screenOrientation="landscape" />
android:name=".CertActivity"
android:exported="true" />
<activity
android:name=".video.VideoActivity"
android:exported="false"
@ -148,11 +93,17 @@
<activity
android:name=".v2.Camera2VideoActivityOld"
android:exported="false"
android:screenOrientation="landscape" />
android:screenOrientation="landscape"
/>
<activity
android:name=".v2.Camera2VideoActivity"
android:exported="false"
android:screenOrientation="landscape" />
android:screenOrientation="landscape"
/>
<activity
android:name=".ChannelActivity"
android:exported="false"
@ -174,10 +125,11 @@
<category android:name="android.intent.category.default" />
</intent-filter>
</service>
<service android:name=".FloatingWindow" />
<receiver
android:name=".MicroPhotoService$AlarmReceiver"
android:exported="true" >
</receiver>
android:exported="true" />
<receiver
android:name=".BootBroadcastReceiver"
android:enabled="true"
@ -191,7 +143,17 @@
</intent-filter>
</receiver>
<receiver android:name=".NetworkChangedReceiver" />
<receiver
android:name=".ScreenActionReceiver"
android:exported="true">
<intent-filter android:priority="90000">
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.USER_UNLOCKED" />
</intent-filter>
</receiver>
<receiver
android:name="com.xypower.common.UpdateReceiver"
android:enabled="true"
@ -204,17 +166,11 @@
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name=".HeartBeatResponseReceiver"
android:enabled="true"
android:exported="true">
<intent-filter >
<action android:name="com.systemui.ACTION_HEARTBEAT_RESPONSE" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -222,6 +178,16 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
</application>
</manifest>

@ -1,227 +0,0 @@
#!/system/bin/sh
# ==============================================
# Configuration parameters - modify as needed
# ==============================================
ETH_IP="192.168.68.91" # Ethernet IP address
ETH_NETMASK="24" # Subnet mask (CIDR format)
ETH_NETWORK="192.168.68.0" # Network address
ETH_BROADCAST="192.168.68.255" # Broadcast address
ETH_GATEWAY="192.168.68.1" # Default gateway
ROUTE_TABLE="20" # Routing table number
MAX_INIT_WAIT=150 # Maximum seconds to wait for ethernet interface
MAX_UP_WAIT=10 # Maximum seconds to wait for interface to come UP
MAX_ROUTE_WAIT=5 # Maximum seconds to wait for routing rules
# For debugging only - comment out in production
# set -x
ANDROID_VERSION=$(getprop ro.build.version.release 2>/dev/null | cut -d '.' -f1)
# Record script start time
SCRIPT_START=$(date +%s)
# Cleanup function - handles unexpected interruptions
cleanup() {
echo "Script interrupted, cleaning up..." >&2
# Add additional cleanup code here if needed
exit 1
}
trap cleanup INT TERM
# Get script directory for finding tools like ethtool
SCRIPT_PATH="$0"
# Ensure path is absolute
case "$SCRIPT_PATH" in
/*) ;; # Already absolute path
*) SCRIPT_PATH="$PWD/$SCRIPT_PATH" ;;
esac
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
echo "Script directory detected as: $SCRIPT_DIR"
# Only configure rp_filter for eth0 interface
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter 2>/dev/null || true
# Wait for eth0 interface to appear
WAITED=0
while [ $WAITED -lt $MAX_INIT_WAIT ]; do
if [ -d "/sys/class/net/eth0" ]; then
echo "eth0 found after $WAITED seconds"
break
fi
echo "Wait eth0... ($WAITED/$MAX_INIT_WAIT)"
sleep 0.1
WAITED=$((WAITED+1))
done
# Check if eth0 exists
if ! [ -d "/sys/class/net/eth0" ]; then
echo "Error: eth0 not exists" >&2
exit 1
fi
# Check physical connection status
if [ -f "/sys/class/net/eth0/carrier" ]; then
CARRIER=$(cat /sys/class/net/eth0/carrier)
echo "Physical connection status: $CARRIER (1=connected, 0=disconnected)"
if [ "$CARRIER" != "1" ]; then
echo "Warning: Ethernet physical connection may have issues, please check the cable" >&2
fi
fi
# Clear previous configuration
/system/bin/ip link set eth0 down
/system/bin/ip addr flush dev eth0
/system/bin/ip route flush dev eth0
/system/bin/ip route flush table $ROUTE_TABLE
/system/bin/ip rule del to $ETH_NETWORK/$ETH_NETMASK 2>/dev/null || true
# Configure physical layer with ethtool (while interface is DOWN)
if [ -x "$SCRIPT_DIR/ethtool" ]; then
echo "Using ethtool from script directory: $SCRIPT_DIR/ethtool"
"$SCRIPT_DIR/ethtool" -s eth0 speed 10 duplex full autoneg off
# Try alternative path next
elif [ -x "/data/data/com.xypower.mpapp/files/ethtool" ]; then
echo "Configuring eth0 to 10Mbps full duplex..."
/data/data/com.xypower.mpapp/files/ethtool -s eth0 speed 10 duplex full autoneg off
else
echo "Warning: ethtool not found, falling back to sysfs configuration" >&2
# Try sysfs configuration as fallback
if [ -f "/sys/class/net/eth0/speed" ]; then
echo "off" > /sys/class/net/eth0/autoneg 2>/dev/null || true
echo "10" > /sys/class/net/eth0/speed 2>/dev/null || true
echo "full" > /sys/class/net/eth0/duplex 2>/dev/null || true
fi
fi
# ====================================================
# MTK Android 9 IP configuration with loss prevention
# ====================================================
# Configure IP address first while interface is DOWN
echo "Setting IP address while interface is DOWN..."
/system/bin/ip addr add $ETH_IP/$ETH_NETMASK broadcast $ETH_BROADCAST dev eth0
PRE_UP_IP=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
echo "IP configuration before UP: $PRE_UP_IP (1=configured, 0=missing)"
# Enable interface and wait for UP
echo "Bringing up interface..."
/system/bin/ip link set eth0 up
if [ "$ANDROID_VERSION" = "9" ]; then
sleep 3
else
# Use standard configuration for other devices
sleep 1
fi
# Check if IP was lost after interface UP (common issue on MTK devices)
POST_UP_IP=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
echo "IP configuration after UP: $POST_UP_IP (1=retained, 0=lost)"
# IP address lost detection and recovery
if [ "$PRE_UP_IP" = "1" ] && [ "$POST_UP_IP" = "0" ]; then
echo "Warning: IP address was lost after bringing interface up - MTK issue detected"
echo "Reapplying IP configuration..."
/system/bin/ip addr add $ETH_IP/$ETH_NETMASK broadcast $ETH_BROADCAST dev eth0
# Check if reapplied configuration worked
FIXED_IP=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
echo "IP reapplication result: $FIXED_IP (1=success, 0=still missing)"
# If standard method fails, try MTK-specific approaches
if [ "$FIXED_IP" = "0" ]; then
echo "Standard IP configuration failed, trying MTK-specific methods"
# Try ifconfig if available (works better on some MTK devices)
if command -v ifconfig >/dev/null 2>&1; then
echo "Using ifconfig method..."
ifconfig eth0 $ETH_IP netmask 255.255.255.0 up
sleep 1
fi
# Try Android's netd service if available
if [ -x "/system/bin/ndc" ]; then
echo "Using MTK netd service..."
/system/bin/ndc network interface setcfg eth0 $ETH_IP 255.255.255.0 up
sleep 1
fi
fi
fi
# Use loop to wait for interface UP instead of fixed sleep
WAITED=0
while [ $WAITED -lt $MAX_UP_WAIT ]; do
# Check both link status and IP configuration
IF_STATUS=$(/system/bin/ip link show eth0 | grep -c ",UP")
IP_STATUS=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
if [ "$IF_STATUS" = "1" ] && [ "$IP_STATUS" = "1" ]; then
echo "Interface is UP with correct IP after $WAITED seconds"
break
fi
echo "Waiting for interface UP with IP... ($WAITED/$MAX_UP_WAIT)"
# If interface is UP but IP is missing, reapply IP
if [ "$IF_STATUS" = "1" ] && [ "$IP_STATUS" = "0" ]; then
echo "Interface UP but IP missing, reapplying IP..."
/system/bin/ip addr add $ETH_IP/$ETH_NETMASK broadcast $ETH_BROADCAST dev eth0
fi
sleep 0.5
WAITED=$((WAITED+1))
done
# Final status check
FINAL_IF_STATUS=$(/system/bin/ip link show eth0 | grep -c ",UP")
FINAL_IP_STATUS=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
if [ "$FINAL_IF_STATUS" != "1" ] || [ "$FINAL_IP_STATUS" != "1" ]; then
echo "Warning: Failed to achieve stable interface state with IP" >&2
echo "Final interface status: $FINAL_IF_STATUS (1=UP, 0=DOWN)"
echo "Final IP status: $FINAL_IP_STATUS (1=configured, 0=missing)"
/system/bin/ip addr show eth0
else
echo "Successfully configured eth0 with IP $ETH_IP"
fi
# First add to main routing table
/system/bin/ip route add $ETH_NETWORK/$ETH_NETMASK dev eth0 proto static scope link
# Then add to specified routing table
/system/bin/ip route add $ETH_NETWORK/$ETH_NETMASK dev eth0 proto static scope link table $ROUTE_TABLE
ADD_ROUTE_STATUS=$?
if [ $ADD_ROUTE_STATUS -eq 0 ]; then
echo "Add route successfully"
else
echo "Failed to add route: $ADD_ROUTE_STATUS" >&2
fi
# Only clear ARP and neighbor cache for eth0
/system/bin/ip neigh flush dev eth0
# Add routing rules - only flush cache once after rule is added
/system/bin/ip rule add from all to $ETH_NETWORK/$ETH_NETMASK lookup $ROUTE_TABLE prio 1000
/system/bin/ip route flush cache dev eth0
# Only enable forwarding for eth0 interface
echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding 2>/dev/null || true
# Wait for routing rules to take effect - using loop check instead of fixed wait
WAITED=0
while [ $WAITED -lt $MAX_ROUTE_WAIT ]; do
if /system/bin/ip rule | grep -q "$ETH_NETWORK/$ETH_NETMASK"; then
echo "Routing rules are now effective after $WAITED seconds"
break
fi
echo "Waiting for routing rules to take effect... ($WAITED/$MAX_ROUTE_WAIT)"
sleep 0.5
WAITED=$((WAITED+1))
done
# Display execution time
SCRIPT_END=$(date +%s)
TOTAL_TIME=$((SCRIPT_END - SCRIPT_START))
echo "Total script execution time: $TOTAL_TIME seconds"
exit 0

Binary file not shown.

Binary file not shown.

@ -14,27 +14,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wformat
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
# SET_TARGET_PROPERTIES(microphoto PROPERTIES LINK_FLAGS "-Wl,-s,--gc-sections")
add_definitions(-DUSING_ETHERNET)
if(ANDROID_ABI STREQUAL "armeabi-v7a")
add_definitions(-DUSING_N938)
elseif(ANDROID_ABI STREQUAL "arm64-v8a")
# add_definitions(-DUSING_N938)
# add_definitions(-DUSING_PTZ)
endif()
# OUTPUT_DBG_INFO:
add_definitions(-DOUTPUT_DBG_INFO)
# OUTPUT_SOCKET_DBG_INFO Depends ON OUTPUT_DBG_INFO
# TerminalService.cpp
# add_definitions(-DOUTPUT_SOCKET_DBG_INFO)
# OUTPUT_DB_DBG_INFO Depends ON OUTPUT_DBG_INFO
# Database.cpp
# add_definitions(-DOUTPUT_DB_DBG_INFO)
add_definitions(-DUSING_FFMPEG)
IF (CMAKE_BUILD_TYPE STREQUAL Debug)
ADD_DEFINITIONS(-D_DEBUG)
ELSE()
@ -49,22 +28,15 @@ add_definitions(-DASIO_STANDALONE)
add_definitions(-DUSING_XY_EXTENSION)
# add_definitions(-DUSING_BREAK_PAD)
add_definitions(-DSQLITE_THREADSAFE=1)
add_definitions(-DLIBRAW_NO_MEMPOOL_CHECK=1)
# add_definitions(-DHDRPLUS_NO_DETAILED_OUTPUT=1)
add_definitions(-DHAVE_STRING_H) # for memcpy in md5.c
# add_definitions(-DUSING_NRSEC)
# add_definitions(-DUSING_NRSEC_VPN)
# add_definitions(-DUSING_CERT)
add_definitions(-DUSING_NRSEC)
# add_definitions(-DUSING_DOWSE)
# OUTPUT_CAMERA_DBG_INFO: CARERA
add_definitions(-DOUTPUT_CAMERA_DBG_INFO)
add_definitions(-DALIGN_HB_TIMER_TO_PHOTO)
add_definitions(-DENABLE_3V3_ALWAYS)
add_definitions(-DCURL_STATICLIB)
add_definitions(-DUSING_HDRPLUS)
add_definitions(-DUSING_EXEC_HDRP=0)
#set(USING_EXEC_HDRP 1)
# set(OpenCV_DIR D:/Workspace/deps/OpenCV-android-sdk/sdk/native/jni/)
set(OPENCV_EXTRA_MODULES_PATH D:/Workspace/Github/opencv_contrib/modules)
# include_directories(${OpenCV_DIR}/include)
# add_library( lib_opencv SHARED IMPORTED )
@ -74,7 +46,10 @@ add_definitions(-DUSING_EXEC_HDRP=0)
project("microphoto")
find_package(OpenCV REQUIRED core imgproc highgui photo)
# message(FATAL_ERROR "OpenCV ${OpenCV_DIR}")
find_package(OpenCV REQUIRED core imgproc highgui)
# find_package(OpenCV REQUIRED core imgproc)
if(OpenCV_FOUND)
include_directories(${OpenCV_INCLUDE_DIRS})
@ -94,115 +69,88 @@ endif(OpenCV_FOUND)
set(ncnn_DIR ${NCNN_ROOT}/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)
# include(mars/src/CMakeUtils.txt)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/breakpad)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libcutils/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libutils/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/img_utils/include)
SET( IMG_UTILS_SRCS
"img_utils/src/EndianUtils.cpp"
#"img_utils/src/FileInput.cpp"
#"img_utils/src/FileOutput.cpp"
#"img_utils/src/SortedEntryVector.cpp"
"img_utils/src/Input.cpp"
"img_utils/src/Output.cpp"
"img_utils/src/Orderable.cpp"
"img_utils/src/TiffIfd.cpp"
"img_utils/src/TiffWritable.cpp"
"img_utils/src/TiffWriter.cpp"
"img_utils/src/TiffEntry.cpp"
"img_utils/src/TiffEntryImpl.cpp"
"img_utils/src/ByteArrayOutput.cpp"
"img_utils/src/DngUtils.cpp"
"img_utils/src/StripSource.cpp"
libutils/SharedBuffer.cpp
libutils/StrongPointer.cpp
DngCreator.cpp
)
message(WARNING "include_directories ${HDRPLUS_ROOT}/${ANDROID_ABI}/include")
include_directories(${HDRPLUS_ROOT}/${ANDROID_ABI}/include)
link_directories(${HDRPLUS_ROOT}/${ANDROID_ABI}/lib)
# message(WARNING "exiv2_DIR=${HDRPLUS_ROOT}/${ANDROID_ABI}/lib/cmake/exiv2")
# SET(exiv2_DIR ${HDRPLUS_ROOT}/${ANDROID_ABI}/lib/cmake/exiv2)
# list(APPEND CMAKE_PREFIX_PATH ${HDRPLUS_ROOT}/${ANDROID_ABI}/lib/cmake/exiv2)
# find_package(exiv2 REQUIRED CONFIG NAMES exiv2)
# message(STATUS "Found Exiv2 and linked")
# OpenMP
find_package(OpenMP REQUIRED)
SET(YAMC_INC_DIR ${CMAKE_SOURCE_DIR})
# SET(TERM_CORE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../xymp/Core)
#SET(TERM_CORE_ROOT D:/shxy/xymp/Core)
# library
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/hdrplus/include )
SET(JSONCPP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp)
SET(JSONCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp/include)
SET(SQLITE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sqlite)
SET(SQLITE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sqlite)
# include_directories(${HDRPLUS_ROOT}/${ANDROID_ABI}/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/hdrplus2)
include_directories(hdrplus2/${ANDROID_ABI})
include_directories(${HALIDE_ROOT}/${ANDROID_ABI}/include)
SET(BREAKPAD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/breakpad)
SET(CAMERA2_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/camera2)
SET(ZLMEDIAKIT_LIBS "")
SET(STREAMING_SRCS "")
SET(FREETYPE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/freetype)
add_definitions(-DDISABLE_RTTI)
# include_directories( ${HDRPLUS_ROOT}/${ANDROID_ABI}/include/ZLMediaKit )
# include_directories( ${HDRPLUS_ROOT}/${ANDROID_ABI}/include/ZLToolKit/src/ )
# SET(ZLMEDIAKIT_LIBS ${ZLMEDIAKIT_LIBS} zlmediakit zltoolkit)
# SET(EVPP_SRC_DIR ${EVPP_ROOT}/evpp)
SET(STREAMING_SRCS media/RTSPToMP4.cpp media/RTSPRecorder.cpp media/Streaming.cpp )
include_directories(${YAMC_INC_DIR})
include_directories(${BREAKPAD_ROOT} ${BREAKPAD_ROOT}/common/android/include)
include_directories(${ASIO_ROOT}/include)
#SET(HDRPLUS_LIBS raw exiv2 exiv2-xmp expat lcms2 OpenMP::OpenMP_CXX)
add_library( # Sets the name of the library.
sqlite3
#SET(HDRPLUS2_LIBS raw raw_r lcms2 tiff tiffxx jpeg hdrplus_pipeline)
# Sets the library as a shared library.
STATIC
SET(HDRPLUS_SOURCES
hdrplus/src/align.cpp
hdrplus/src/bayer_image.cpp
hdrplus/src/burst.cpp
hdrplus/src/finish.cpp
hdrplus/src/hdrplus_pipeline.cpp
hdrplus/src/merge.cpp
hdrplus/src/params.cpp
# Provides a relative path to your source file(s).
${SQLITE_SRC_DIR}/sqlite3.c
)
SET(HDRPLUS2_SOURCES
hdrplus2/src/HDRPlus.cpp
hdrplus2/src/Burst.cpp
hdrplus2/src/InputSource.cpp
hdrplus2/src/LibRaw2DngConverter.cpp
hdrplus2/${ANDROID_ABI}/hdrplus_pipeline.registration.cpp)
SET(HDRPLUS2_SOURCES )
SET(YAMC_INC_DIR ${CMAKE_SOURCE_DIR})
# SET(TERM_CORE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../xymp/Core)
#SET(TERM_CORE_ROOT D:/shxy/xymp/Core)
INCLUDE_DIRECTORIES(${SQLITE_INCLUDE_DIR})
file(GLOB BREAKPAD_SOURCES_COMMON
native-lib.cpp
${BREAKPAD_ROOT}/client/linux/crash_generation/crash_generation_client.cc
${BREAKPAD_ROOT}/client/linux/dump_writer_common/thread_info.cc
${BREAKPAD_ROOT}/client/linux/dump_writer_common/ucontext_reader.cc
${BREAKPAD_ROOT}/client/linux/handler/exception_handler.cc
${BREAKPAD_ROOT}/client/linux/handler/minidump_descriptor.cc
${BREAKPAD_ROOT}/client/linux/log/log.cc
${BREAKPAD_ROOT}/client/linux/microdump_writer/microdump_writer.cc
${BREAKPAD_ROOT}/client/linux/minidump_writer/linux_dumper.cc
${BREAKPAD_ROOT}/client/linux/minidump_writer/linux_ptrace_dumper.cc
${BREAKPAD_ROOT}/client/linux/minidump_writer/minidump_writer.cc
${BREAKPAD_ROOT}/client/linux/minidump_writer/pe_file.cc
${BREAKPAD_ROOT}/client/minidump_file_writer.cc
${BREAKPAD_ROOT}/common/convert_UTF.cc
${BREAKPAD_ROOT}/common/md5.cc
${BREAKPAD_ROOT}/common/string_conversion.cc
${BREAKPAD_ROOT}/common/linux/elfutils.cc
${BREAKPAD_ROOT}/common/linux/file_id.cc
${BREAKPAD_ROOT}/common/linux/guid_creator.cc
${BREAKPAD_ROOT}/common/linux/linux_libc_support.cc
${BREAKPAD_ROOT}/common/linux/memory_mapped_file.cc
${BREAKPAD_ROOT}/common/linux/safe_readlink.cc
)
SET(JSONCPP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp)
SET(JSONCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp/include)
file(GLOB BREAKPAD_ASM_SOURCE ${BREAKPAD_ROOT}/common/linux/breakpad_getcontext.S)
set_property(SOURCE ${BREAKPAD_ROOT}/common/linux/breakpad_getcontext.S PROPERTY LANGUAGE C)
# set_source_files_properties(${BREAKPAD_ASM_SOURCE} PROPERTIES LANGUAGE C)
SET(CAMERA2_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/camera2)
# 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.
SET(FREETYPE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/freetype)
add_library( # Sets the name of the library.
breakpad
# SET(EVPP_SRC_DIR ${EVPP_ROOT}/evpp)
# Sets the library as a shared library.
STATIC
include_directories(${YAMC_INC_DIR})
include_directories(${ASIO_ROOT}/include)
# Provides a relative path to your source file(s).
${BREAKPAD_SOURCES_COMMON}
${BREAKPAD_ASM_SOURCE}
)
# SET(SQLITE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sqlite)
# SET(SQLITE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sqlite)
# add_library(sqlite3 STATIC ${SQLITE_SRC_DIR}/sqlite3.c )
# INCLUDE_DIRECTORIES(${SQLITE_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${JSONCPP_INCLUDE_DIR})
@ -288,6 +236,31 @@ include_directories(${FREETYPE_ROOT}/include)
include_directories(${TERM_CORE_ROOT})
# include_directories(${PROJECT_SOURCE_DIR}/../../../../../libs/inc/)
#[[
add_library( # Sets the name of the library.
evpp_lite
# Sets the library as a shared library.
STATIC
# Provides a relative path to your source file(s).
${EVPP_SOURCES} )
]]
IF (CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
# set(BOOST_ROOT C:/ProgramData/boost_1_82_0/)
# set(BOOST_INCLUDEDIR C:/ProgramData/boost_1_82_0/)
include_directories(C:/ProgramData/boost_1_82_0/)
ELSE()
# find_package(Boost 1.58.0 COMPONENTS)
find_package(Boost 1.58.0)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
else()
message(FATAL_ERROR "Boost Not Found")
endif()
endif()
# 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.
@ -296,8 +269,10 @@ include_directories(${TERM_CORE_ROOT})
add_library( # Sets the name of the library.
jsoncpp
# Sets the library as a shared library.
STATIC
# Provides a relative path to your source file(s).
${JSONCPP_SOURCES}
)
@ -310,25 +285,6 @@ add_library(
${FREETYPE_SRC_FILES}
)
if(USING_EXEC_HDRP)
message(WARNING "HDRP Compiled")
add_executable( libhdrp.so
${HDRPLUS_SOURCES}
hdrplus/bin/hdrplus.cpp )
target_link_libraries( libhdrp.so PUBLIC -fopenmp -static-openmp
android z
${OpenCV_LIBS}
# ${LIBRAW_LIBRARY}
${HDRPLUS_LIBS}
)
else(USING_EXEC_HDRP)
endif()
SET(HDRPLUS_SOURCES_EMBED ${HDRPLUS2_SOURCES} )
SET(HDRPLUS_LIBS_EMBED ${HDRPLUS2_LIBS} )
add_library( # Sets the name of the library.
microphoto
@ -338,8 +294,8 @@ add_library( # Sets the name of the library.
# Provides a relative path to your source file(s).
GPIOControl.cpp
MicroPhoto.cpp
TerminalDevice.cpp
PhoneDevice.cpp
PtzController.cpp
# PhoneDevice2.cpp
Camera.cpp
Camera2Reader.cpp
@ -348,27 +304,14 @@ add_library( # Sets the name of the library.
SerialPort.cpp
#WeatherComm.cpp
SensorsProtocol.cpp
SerialComm.cpp
serialComm.cpp
ncnn/yolov5ncnn.cpp
netcamera/httpclient.cpp
netcamera/VendorCtrl.cpp
netcamera/YuShiCtrl.cpp
netcamera/HangYuCtrl.cpp
netcamera/HikonCtrl.cpp
${STREAMING_SRCS}
#serial/WeatherComm.cpp
# camera2/OpenCVFont.cpp
${HDRPLUS_SOURCES_EMBED}
${CAMERA2_SOURCES}
${IMG_UTILS_SRCS}
${TERM_CORE_ROOT}/Factory.cpp
${TERM_CORE_ROOT}/FilePoster.cpp
${TERM_CORE_ROOT}/LogThread.cpp
@ -378,11 +321,9 @@ add_library( # Sets the name of the library.
${TERM_CORE_ROOT}/SpecData_I1_JS.cpp
${TERM_CORE_ROOT}/SpecData_I1_HN.cpp
${TERM_CORE_ROOT}/SpecData_I1_HEN.cpp
${TERM_CORE_ROOT}/SpecData_I1_HEN_TY.cpp
${TERM_CORE_ROOT}/SpecData_I1_HENZZ.cpp
${TERM_CORE_ROOT}/SpecData_I1_SHX.cpp
${TERM_CORE_ROOT}/SpecData_I1_NX.cpp
${TERM_CORE_ROOT}/SpecData_I1_SX_ZY.cpp
${TERM_CORE_ROOT}/SpecData_XY.cpp
${TERM_CORE_ROOT}/SpecData_ZJ.cpp
${TERM_CORE_ROOT}/SpecData_NW.cpp
@ -400,18 +341,13 @@ add_library( # Sets the name of the library.
${TERM_CORE_ROOT}/Client/Terminal_AH.cpp
${TERM_CORE_ROOT}/Client/Terminal_HEN_ZZ.cpp
${TERM_CORE_ROOT}/Client/Terminal_HEN.cpp
${TERM_CORE_ROOT}/Client/Terminal_HEN_TY.cpp
${TERM_CORE_ROOT}/Client/Terminal_SHX.cpp
${TERM_CORE_ROOT}/Client/Terminal_JS.cpp
${TERM_CORE_ROOT}/Client/Terminal_NX.cpp
${TERM_CORE_ROOT}/Client/Terminal_SX_ZY.cpp
${TERM_CORE_ROOT}/Client/Terminal_ZJ.cpp
${TERM_CORE_ROOT}/Client/Terminal_NW.cpp
${TERM_CORE_ROOT}/Client/DataController.cpp
${TERM_CORE_ROOT}/Client/UpgradeReceiver.cpp
${TERM_CORE_ROOT}/Client/Database.cpp
# ${TERM_CORE_ROOT}/Client/SimulatorDevice.cpp
${TERM_CORE_ROOT}/Client/DataController.cpp
)
@ -432,17 +368,23 @@ find_library( # Sets the name of the path variable.
# 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.
${PROJECT_NAME}
microphoto
jsoncpp
freetype
breakpad
# breakpad
# Links the target library to the log library
# included in the NDK.
avcodec avfilter avformat avutil swresample swscale x264
${log-lib}
android camera2ndk mediandk z curl
ncnn ${OpenCV_LIBS} sqlite3 ${HDRPLUS_LIBS_EMBED} ${ZLMEDIAKIT_LIBS}
android camera2ndk mediandk z
ncnn ${OpenCV_LIBS} sqlite3
)
# set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "-strip-all")

@ -1,3 +1,4 @@
#include "TerminalDevice.h"
/*
* Copyright 2018 The Android Open Source Project
*

@ -354,24 +354,13 @@ namespace cv {
mvFn(NULL, (void*)userData);
// Update current position ( in FreeType coordinates )
#if defined(USING_HB)
currentPos.x += mFace->glyph->advance.x;
#else
if (wstr[i] == ' ')
{
currentPos.x += mFace->glyph->advance.x << 1;
}
else
{
currentPos.x += mFace->glyph->advance.x;
}
#endif
currentPos.y += mFace->glyph->advance.y;
}
delete userData;
#if defined(USING_HB)
hb_buffer_destroy(hb_buffer);
#endif // 0
#endif 0
}
// https://freetype.org/freetype2/docs/tutorial/example2.cpp
@ -630,7 +619,7 @@ namespace cv {
#if defined(USING_HB)
hb_buffer_destroy(hb_buffer);
#endif // 0
#endif 0
}
Size FreeType2Impl::getTextSize(
@ -1047,19 +1036,7 @@ namespace cv {
(this->*putPixel)(dst, gPos.y + row, gPos.x + col, _colorUC8n, cl);
}
}
#if defined(USING_HB)
_org.x += (mFace->glyph->advance.x) >> 6;
#else
if (wstr[i] == ' ')
{
_org.x += ((mFace->glyph->advance.x) >> 6) << 1;
}
else
{
_org.x += (mFace->glyph->advance.x) >> 6;
}
#endif
_org.x += (mFace->glyph->advance.x) >> 6;
_org.y += (mFace->glyph->advance.y) >> 6;
}
@ -1068,6 +1045,7 @@ namespace cv {
#endif
}
int FreeType2Impl::mvFn(const FT_Vector *to, void * user)
{
if (user == NULL) { return 1; }

File diff suppressed because it is too large Load Diff

@ -1,332 +0,0 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "DngCreator_JNI"
#include <inttypes.h>
#include <string.h>
#include <algorithm>
#include <array>
#include <memory>
#include <vector>
#include <cmath>
#include <algorithm>
#include <camera/NdkCameraMetadata.h>
#include <img_utils/DngUtils.h>
#include <img_utils/TagDefinitions.h>
#include <img_utils/TiffIfd.h>
#include <img_utils/TiffWriter.h>
#include <img_utils/Output.h>
#include <img_utils/Input.h>
#include <img_utils/StripSource.h>
#include <sys/system_properties.h>
// #include "core_jni_helpers.h"
// #include "android_runtime/AndroidRuntime.h"
// #include "android_runtime/android_hardware_camera2_CameraMetadata.h"
#include <jni.h>
// #include <nativehelper/JNIHelp.h>
using namespace android;
using namespace img_utils;
// using android::base::GetProperty;
/**
* Max width or height dimension for thumbnails.
*/
// max pixel dimension for TIFF/EP
#define MAX_THUMBNAIL_DIMENSION 256
// bytes per sample
#define DEFAULT_PIXEL_STRIDE 2
// byts per pixel
#define BYTES_PER_RGB_PIX 3
#define GPS_LAT_REF_NORTH "N"
#define GPS_LAT_REF_SOUTH "S"
#define GPS_LONG_REF_EAST "E"
#define GPS_LONG_REF_WEST "W"
#define GPS_DATE_FORMAT_STR "yyyy:MM:dd"
#define TIFF_DATETIME_FORMAT "yyyy:MM:dd kk:mm:ss"
class ByteVectorOutput : public Output {
public:
ByteVectorOutput(std::vector<uint8_t>& buf);
virtual ~ByteVectorOutput();
virtual status_t open();
virtual status_t write(const uint8_t* buf, size_t offset, size_t count);
virtual status_t close();
protected:
std::vector<uint8_t>& m_buf;
};
class ByteVectorInput : public Input {
public:
ByteVectorInput(const std::vector<uint8_t>& buf);
virtual ~ByteVectorInput();
/**
* Open this Input.
*
* Returns OK on success, or a negative error code.
*/
status_t open();
/**
* Read bytes into the given buffer. At most, the number of bytes given in the
* count argument will be read. Bytes will be written into the given buffer starting
* at the index given in the offset argument.
*
* Returns the number of bytes read, or NOT_ENOUGH_DATA if at the end of the file. If an
* error has occurred, this will return a negative error code other than NOT_ENOUGH_DATA.
*/
ssize_t read(uint8_t* buf, size_t offset, size_t count);
/**
* Skips bytes in the input.
*
* Returns the number of bytes skipped, or NOT_ENOUGH_DATA if at the end of the file. If an
* error has occurred, this will return a negative error code other than NOT_ENOUGH_DATA.
*/
ssize_t skip(size_t count);
/**
* Close the Input. It is not valid to call open on a previously closed Input.
*
* Returns OK on success, or a negative error code.
*/
status_t close();
protected:
const std::vector<uint8_t>& m_buf;
size_t m_offset;
};
class ByteBufferInput : public Input {
public:
ByteBufferInput(const uint8_t* buf, size_t len);
virtual ~ByteBufferInput();
/**
* Open this Input.
*
* Returns OK on success, or a negative error code.
*/
status_t open();
/**
* Read bytes into the given buffer. At most, the number of bytes given in the
* count argument will be read. Bytes will be written into the given buffer starting
* at the index given in the offset argument.
*
* Returns the number of bytes read, or NOT_ENOUGH_DATA if at the end of the file. If an
* error has occurred, this will return a negative error code other than NOT_ENOUGH_DATA.
*/
ssize_t read(uint8_t* buf, size_t offset, size_t count);
/**
* Skips bytes in the input.
*
* Returns the number of bytes skipped, or NOT_ENOUGH_DATA if at the end of the file. If an
* error has occurred, this will return a negative error code other than NOT_ENOUGH_DATA.
*/
ssize_t skip(size_t count);
/**
* Close the Input. It is not valid to call open on a previously closed Input.
*
* Returns OK on success, or a negative error code.
*/
status_t close();
protected:
const uint8_t* m_buf;
size_t m_len;
size_t m_offset;
};
struct SIZE
{
int width;
int height;
};
#define BAIL_IF_INVALID_RET_BOOL(expr, jnienv, tagId, writer) \
if ((expr) != OK) { \
return false; \
}
#define BAIL_IF_INVALID_RET_NULL_SP(expr, jnienv, tagId, writer) \
if ((expr) != OK) { \
return nullptr; \
}
#define BAIL_IF_INVALID_R(expr, jnienv, tagId, writer) \
if ((expr) != OK) { \
return -1; \
}
#define BAIL_IF_EMPTY_RET_NULL_SP(entry, jnienv, tagId, writer) \
if ((entry).count == 0) { \
return nullptr; \
}
#define BAIL_IF_EXPR_RET_NULL_SP(expr, jnienv, tagId, writer) \
if (expr) { \
return nullptr; \
}
#define ANDROID_DNGCREATOR_CTX_JNI_ID "mNativeContext"
enum {
BITS_PER_SAMPLE = 16,
BYTES_PER_SAMPLE = 2,
BYTES_PER_RGB_PIXEL = 3,
BITS_PER_RGB_SAMPLE = 8,
BYTES_PER_RGB_SAMPLE = 1,
SAMPLES_PER_RGB_PIXEL = 3,
SAMPLES_PER_RAW_PIXEL = 1,
TIFF_IFD_0 = 0,
TIFF_IFD_SUB1 = 1,
TIFF_IFD_GPSINFO = 2,
};
/**
* POD container class for GPS tag data.
*/
class GpsData {
public:
enum {
GPS_VALUE_LENGTH = 6,
GPS_REF_LENGTH = 2,
GPS_DATE_LENGTH = 11,
};
uint32_t mLatitude[GPS_VALUE_LENGTH];
uint32_t mLongitude[GPS_VALUE_LENGTH];
uint32_t mTimestamp[GPS_VALUE_LENGTH];
uint8_t mLatitudeRef[GPS_REF_LENGTH];
uint8_t mLongitudeRef[GPS_REF_LENGTH];
uint8_t mDate[GPS_DATE_LENGTH];
};
// ----------------------------------------------------------------------------
/**
* Container class for the persistent native context.
*/
class NativeContext : public LightRefBase<NativeContext> {
public:
enum {
DATETIME_COUNT = 20,
};
NativeContext(ACameraMetadata* characteristics, ACameraMetadata* result);
virtual ~NativeContext();
TiffWriter* getWriter();
ACameraMetadata* getCharacteristics() const;
ACameraMetadata* getResult() const;
uint32_t getThumbnailWidth() const;
uint32_t getThumbnailHeight() const;
const uint8_t* getThumbnail() const;
bool hasThumbnail() const;
bool setThumbnail(const std::vector<uint8_t>& buffer, uint32_t width, uint32_t height);
void setOrientation(uint16_t orientation);
uint16_t getOrientation() const;
void setDescription(const std::string& desc);
std::string getDescription() const;
bool hasDescription() const;
void setGpsData(const GpsData& data);
GpsData getGpsData() const;
bool hasGpsData() const;
void setCaptureTime(const std::string& formattedCaptureTime);
std::string getCaptureTime() const;
bool hasCaptureTime() const;
protected:
std::vector<uint8_t> mCurrentThumbnail;
TiffWriter mWriter;
ACameraMetadata* mCharacteristics;
ACameraMetadata* mResult;
uint32_t mThumbnailWidth;
uint32_t mThumbnailHeight;
uint16_t mOrientation;
bool mThumbnailSet;
bool mGpsSet;
bool mDescriptionSet;
bool mCaptureTimeSet;
std::string mDescription;
GpsData mGpsData;
std::string mFormattedCaptureTime;
};
class DngCreator : public NativeContext
{
public:
DngCreator(ACameraMetadata* characteristics, ACameraMetadata* result);
#if 0
void setLocation(Location location);
#endif
void writeInputStream(std::vector<uint8_t>& dngOutput, SIZE size, const std::vector<uint8_t>& pixels, long offset);
void writeByteBuffer(std::vector<uint8_t>& dngOutput, SIZE size, const std::vector<uint8_t>& pixels, long offset);
#if 0
void writeImage(OutputStream& dngOutput, AImage& pixels);
#endif
void close();
// private static final DateFormat sExifGPSDateStamp = new SimpleDateFormat(GPS_DATE_FORMAT_STR);
// private static final DateFormat sDateTimeStampFormat = new SimpleDateFormat(TIFF_DATETIME_FORMAT);
#if 0
static {
sDateTimeStampFormat.setTimeZone(TimeZone.getDefault());
sExifGPSDateStamp.setTimeZone(TimeZone.getTimeZone("UTC"));
}
#endif
/**
* Offset, rowStride, and pixelStride are given in bytes. Height and width are given in pixels.
*/
void writeByteBuffer(int width, int height, const std::vector<uint8_t>& pixels, std::vector<uint8_t>& dngOutput, int pixelStride, int rowStride, long offset);
/**
* Generate a direct RGB {@link ByteBuffer} from a {@link Bitmap}.
*/
/**
* Convert coordinate to EXIF GPS tag format.
*/
void toExifLatLong(double value, int data[6]);
void init(ACameraMetadata* characteristics, ACameraMetadata* result, const std::string& captureTime);
sp<TiffWriter> setup(uint32_t imageWidth, uint32_t imageHeight);
void destroy();
void setGpsTags(const std::vector<int>& latTag, const std::string& latRef, const std::vector<int>& longTag, const std::string& longRef, const std::string& dateTag, const std::vector<int>& timeTag);
void writeImage(std::vector<uint8_t>& out, uint32_t width, uint32_t height, const std::vector<uint8_t>& rawBuffer, int rowStride, int pixStride, uint64_t offset, bool isDirect);
void writeInputStream(std::vector<uint8_t>& out, const std::vector<uint8_t>& rawStream, uint32_t width, uint32_t height, long offset);
void writeInputBuffer(std::vector<uint8_t>& out, const uint8_t* rawBuffer, size_t bufferLen, uint32_t width, uint32_t height, long offset);
};

@ -11,7 +11,6 @@
#include <sys/mman.h>
#include <unistd.h>
#include <climits>
#include "GPIOControl.h"
@ -21,144 +20,46 @@
#define IOT_PARAM_WRITE 0xAE
#define IOT_PARAM_READ 0xAF
std::mutex GpioControl::m_locker;
std::mutex GpioControl::m_gpioLocker;
std::vector<GpioControl::ITEM> GpioControl::m_items;
bool GpioControl::m_cameraPowerStatus = false;
#define ENABLE_GPIO_TRACING
#ifdef ENABLE_GPIO_TRACING
class GpioDebugLogger
{
public:
GpioDebugLogger(int cmd, int value)
{
m_startTime = GetMicroTimeStamp();
m_path = std::string("/sdcard/com.xypower.mpapp/tmp/") + std::to_string(cmd) + std::string("_") + std::to_string(m_startTime) + "_val." + std::to_string(value);
CreateEmptyFile(m_path + ".enter");
}
GpioDebugLogger(int cmd)
{
m_startTime = GetMicroTimeStamp();
m_path = std::string("/sdcard/com.xypower.mpapp/tmp/") + std::to_string(cmd) + std::string("_") + std::to_string(m_startTime) + "_get";
CreateEmptyFile(m_path + ".enter");
}
~GpioDebugLogger()
{
uint64_t ts = (GetMicroTimeStamp() - m_startTime);
if (ts > 1000)
{
CreateEmptyFile(m_path + ".leave." + std::to_string(ts));
}
else
{
std::string path = m_path + ".enter";
std::remove(path.c_str());
}
}
private:
std::string m_path;
uint64_t m_startTime;
};
#endif
size_t GpioControl::turnOnImpl(const IOT_PARAM& param)
{
size_t oldRef = 0;
size_t references = 1;
std::vector<ITEM>::iterator it;
int res = 0;
int fd = -1;
time_t now = time(NULL);
// check res???
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == param.cmd)
{
oldRef = it->references;
it->references++;
// it->closeTime = 0;
references = it->references;
if(it->openTime == 0)
it->openTime = now;
SetCamerastatus(it->cmd, true);
break;
}
}
if (it == m_items.end())
{
oldRef = 0;
ITEM item = {param.cmd, references, now};
m_items.push_back(item);
SetCamerastatus(param.cmd, true);
}
if (oldRef == 0/* || param.cmd != CMD_SET_3V3_PWR_EN*/)
{
#ifdef ENABLE_GPIO_TRACING
GpioDebugLogger logger(param.cmd, param.value);
#endif
m_gpioLocker.lock();
fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
res = ioctl(fd, IOT_PARAM_WRITE, &param);
close(fd);
#ifdef OUTPUT_DBG_INFO
// int realVal = getInt(param.cmd);
// XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d RealVal=%d",param.cmd, param.value, param.result/*, realVal*/);
XYLOG(XYLOG_SEVERITY_DEBUG, "setInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
#endif
}
m_gpioLocker.unlock();
#ifdef _DEBUG
ALOGI("PWR TurnOn cmd=%d,result=%d ref=%u\r\n",param.cmd, param.result, (uint32_t)references);
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return references;
}
#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)
{
IOT_PARAM param = { cmd, value, 0 };
// param.cmd = cmd;
// param.value = value;
#ifdef ENABLE_GPIO_TRACING
GpioDebugLogger logger(cmd, value);
#endif
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
if (fd > 0)
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, &param);
// LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
close(fd);
#ifdef OUTPUT_DBG_INFO
// int realVal = getInt(param.cmd);
// XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d RealVal=%d",param.cmd, value, param.result/*, realVal*/);
XYLOG(XYLOG_SEVERITY_DEBUG, "setInt cmd=%d,value=%d,result=%d",param.cmd, value, param.result);
#endif
}
m_gpioLocker.unlock();
return;
}
int GpioControl::getInt(int cmd)
{
#ifdef ENABLE_GPIO_TRACING
GpioDebugLogger logger(cmd);
#endif
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
int fd = open("/dev/mtkgpioctrl", O_RDONLY);
// LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
if( fd > 0 )
{
@ -166,38 +67,33 @@ int GpioControl::getInt(int cmd)
param.cmd = cmd;
ioctl(fd, IOT_PARAM_READ, &param);
#ifdef _DEBUG
ALOGI("getInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
#endif
close(fd);
m_gpioLocker.unlock();
return param.value;
}
m_gpioLocker.unlock();
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);
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
ioctl(fd, IOT_PARAM_WRITE, &param);
// LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
close(fd);
}
m_gpioLocker.unlock();
}
long GpioControl::getLong(int cmd)
{
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
int fd = open("/dev/mtkgpioctrl", O_RDONLY);
// LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd);
if( fd > 0 )
{
@ -206,38 +102,34 @@ long GpioControl::getLong(int cmd)
ioctl(fd, IOT_PARAM_READ, &param);
// LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
close(fd);
m_gpioLocker.unlock();
return param.value2;
}
m_gpioLocker.unlock();
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);
int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
memcpy(param.str, value.c_str(), len);
// LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
ioctl(fd, IOT_PARAM_WRITE, &param);
// LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
close(fd);
}
m_gpioLocker.unlock();
return;
}
std::string GpioControl::getString(int cmd)
{
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
int fd = open("/dev/mtkgpioctrl", O_RDONLY);
// LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd);
if( fd > 0 )
{
@ -246,273 +138,7 @@ std::string GpioControl::getString(int cmd)
ioctl(fd, IOT_PARAM_READ, &param);
// LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
close(fd);
m_gpioLocker.unlock();
return std::string(param.str);
}
m_gpioLocker.unlock();
return "";
}
/////////////////////////// Power Control /////////////////////////////////
size_t GpioControl::TurnOn(int cmd)
{
IOT_PARAM param = { cmd, 1, 0 };
// param.cmd = cmd;
// param.value = value;
m_locker.lock();
size_t ref = turnOnImpl(param);
m_locker.unlock();
return ref;
}
size_t GpioControl::TurnOn(const std::vector<int>& cmds)
{
IOT_PARAM param = { 0, 1, 0 };
// param.cmd = cmd;
// param.value = value;
std::vector<int>::const_iterator it;
m_locker.lock();
for (it = cmds.cbegin(); it != cmds.cend(); ++it)
{
if (*it == 0)
{
continue;
}
param.cmd = *it;
turnOnImpl(param);
}
m_locker.unlock();
return 0;
}
size_t GpioControl::TurnOffImmediately(int cmd)
{
time_t ts = time(NULL);
size_t ref = 0;
std::vector<ITEM>::iterator it;
m_locker.lock();
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == cmd)
{
if (it->references > 0)
{
it->references = 0;
SetCamerastatus(cmd, false);
setInt(it->cmd, 0);
it->openTime = 0;
}
break;
}
}
m_locker.unlock();
#ifdef _DEBUG
ALOGI("PWR TurnOffNow cmd=%d ref=%u", cmd, (uint32_t)ref);
#endif
return 0;
}
size_t GpioControl::TurnOff(int cmd, uint32_t delayedCloseTime/* = 0*/)
{
time_t ts = 0;
if (delayedCloseTime > 0)
{
ts = time(NULL) + delayedCloseTime;
}
size_t ref = 0;
std::vector<ITEM>::iterator it;
if (delayedCloseTime > 0)
{
std::shared_ptr<PowerControl> powerCtrl = std::make_shared<PowerControl>(cmd);
std::thread th([delayedCloseTime, powerCtrl]() mutable {
std::this_thread::sleep_for(std::chrono::seconds(delayedCloseTime));
powerCtrl.reset();
});
th.detach();
}
m_locker.lock();
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == cmd)
{
if (it->references > 0)
{
it->references--;
if (it->references == 0)
{
SetCamerastatus(cmd, false);
setInt(it->cmd, 0);
it->openTime = 0;
}
}
break;
}
}
m_locker.unlock();
#ifdef _DEBUG
ALOGI("PWR TurnOff cmd=%d ref=%u", cmd, (uint32_t)ref);
#endif
return 0;
}
size_t GpioControl::TurnOff(const std::vector<int>& cmds, uint32_t delayedCloseTime/* = 0*/)
{
time_t ts = 0;
if (delayedCloseTime > 0)
{
ts = time(NULL) + delayedCloseTime;
}
std::vector<ITEM>::iterator it;
std::vector<int>::const_reverse_iterator itCmd;
if (delayedCloseTime > 0)
{
std::shared_ptr<PowerControl> powerCtrl = std::make_shared<PowerControl>(cmds);
std::thread th([delayedCloseTime, powerCtrl]() mutable {
std::this_thread::sleep_for(std::chrono::seconds(delayedCloseTime));
powerCtrl.reset();
});
th.detach();
}
m_locker.lock();
// turnOnImpl(param);
for (itCmd = cmds.crbegin(); itCmd != cmds.crend(); ++itCmd)
{
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == *itCmd)
{
if (it->references > 0)
{
it->references--;
if (it->references == 0)
{
SetCamerastatus(it->cmd, false);
setInt(it->cmd, 0);
it->openTime = 0;
}
}
break;
}
}
}
m_locker.unlock();
return 0;
}
size_t GpioControl::TurnOff(const std::vector<std::pair<int, uint32_t> >& cmds)
{
for (auto itCmd = cmds.cbegin(); itCmd != cmds.end(); ++itCmd)
{
if (itCmd->second > 0)
{
uint32_t delayedCloseTime = itCmd->second;
std::shared_ptr<PowerControl> powerCtrl = std::make_shared<PowerControl>(itCmd->first);
std::thread th([delayedCloseTime, powerCtrl]() mutable {
std::this_thread::sleep_for(std::chrono::seconds(delayedCloseTime));
powerCtrl.reset();
});
th.detach();
}
}
std::vector<ITEM>::iterator it;
std::vector<std::pair<int, uint32_t> >::const_iterator itCmd;
m_locker.lock();
for (itCmd = cmds.cbegin(); itCmd != cmds.end(); ++itCmd)
{
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == itCmd->first)
{
if (it->references > 0)
{
it->references--;
if (it->references == 0)
{
SetCamerastatus(it->cmd, false);
setInt(it->cmd, 0);
it->openTime = 0;
}
}
break;
}
}
}
m_locker.unlock();
return 0;
}
bool GpioControl::SetCamerastatus(int cmd, bool status)
{
#ifdef USING_N938
if(cmd == CMD_SET_PIC1_POWER)
m_cameraPowerStatus = status;
#endif
#ifdef USING_PTZ
if(cmd == CMD_SET_PTZ_PWR_ENABLE)
{
m_cameraPowerStatus = status;
}
#endif
return true;
}
bool GpioControl::GetCamerastatus()
{
return m_cameraPowerStatus;
}
bool GpioControl::GetSelftestStatus(time_t wait_time)
{
int cmd = 0;
#ifdef USING_N938
cmd = CMD_SET_PIC1_POWER;
#endif
#ifdef USING_PTZ
cmd = CMD_SET_PTZ_PWR_ENABLE;
#endif
time_t now = time(NULL);
std::vector<ITEM>::iterator it;
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == cmd && it->references > 0 && it->openTime!=0 && (now - it->openTime >= wait_time))
{
return true;//自检完成
}
}
return false;
}
time_t GpioControl::GetSelfTestRemain(time_t wait_time)
{
int cmd = 0;
#ifdef USING_N938
cmd = CMD_SET_PIC1_POWER;
#endif
#ifdef USING_PTZ
cmd = CMD_SET_PTZ_PWR_ENABLE;
#endif
time_t now = time(NULL);
std::vector<ITEM>::iterator it;
for (it = m_items.begin(); it != m_items.end(); ++it)
{
if (it->cmd == cmd && it->references > 0)
{
time_t remaintime = (now - it->openTime);
remaintime = (wait_time > remaintime) ? (wait_time - remaintime) : 0;
return remaintime;//自检完成
}
}
return 0;
}

@ -6,18 +6,6 @@
#define MICROPHOTO_GPIOCONTROL_H
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <vector>
#include <utility>
#include <SemaphoreEx.h>
#include <LogThread.h>
#ifndef USING_N938
#ifndef USING_PTZ // MicroPhoto
#define CMD_GET_LIGHT_ADC 101
#define CMD_SET_LIGHT_ADC 102
@ -27,188 +15,43 @@
#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_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_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_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 // Removed
#define CMD_SET_ALM_MODE 128 // Removed
#define CMD_SET_SYSTEM_RESET 202
#define CMD_SET_SYSTEM_RESET2 203
#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
#if 1
#define CMD_SET_SPI_POWER 129
#define CMD_SET_3V3_PWR_EN 132
#endif
#define CMD_GET_CAMERA_STATUS 310
#define CMD_SET_MADA_INIT_STATUS 312
#define CMD_SET_MADA_CLOSE_STATUS 313
#define CMD_SET_MADA_REG 314
#define CMD_GET_MADA_REG 315
#define CMD_SET_INIT_STATUS 401
#define CMD_SET_5V_PWR_ENABLE 517
#define CMD_SET_NEW_OTG_STATE 507
#else // defined(USING_PTZ)
#define CMD_SET_OTG_STATE 107
#define CMD_GET_OTG_STATE 108
#define CMD_SET_SPI_POWER 129
#define CMD_SET_MADA_MOVE_STATUS 311
#define CMD_SET_12V_EN_STATE 0 // TO BE ADDED
#define CMD_SET_SYSTEM_RESET 202
#define CMD_SET_SYSTEM_RESET2 203
#define CMD_GET_LIGHT_ADC 101
#define CMD_SET_LIGHT_ADC 102
#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112
#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117
#define CMD_SET_SPI_MODE 0 // TO BE ADDED
#define CMD_SET_SPI_BITS_PER_WORD 0 // TO BE ADDED
#define CMD_SET_SPI_MAXSPEEDHZ 0 // TO BE ADDED
#define CMD_SET_485_ENABLE 131
#define CMD_SET_3V3_PWR_EN 132
// #define CMD_SET_5V_PWR_ENABLE 517
#define CMD_SET_SENSOR_ENABLE 504
#define CMD_SET_SENSOR_PWR_ENABLE 505
#define CMD_SET_SENSOR2_ENABLE 506
#define CMD_SET_SENSOR4_ENABLE 510
#define CMD_SET_SENSOR1_PWR_ENABLE 513
#define CMD_SET_SENSOR2_PWR_ENABLE 514
#define CMD_SET_SENSOR3_PWR_ENABLE 509
#define CMD_SET_SENSOR4_PWR_ENABLE 525
#define CMD_SET_PHOTO_IN 520
#define CMD_SET_PHOTO_OUT 515
#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_SD_DECT 507
#define CMD_SET_PTZ_PWR_ENABLE 508
#define CMD_SET_RTC_ENABLE 511
#define CMD_SET_100M_ENABLE 518
#define CMD_SET_100M_SWITCH_PWR_ENABLE 519
#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_100M_RESET 526
#define CMD_GET_CAMERA_STATUS 310
#define CMD_SET_MADA_MOVE_STATUS 311
#define CMD_SET_MADA_INIT_STATUS 312
#define CMD_SET_MADA_CLOSE_STATUS 313
#define CMD_SET_MADA_REG 314
#define CMD_GET_MADA_REG 315
#define CMD_SET_INIT_STATUS 401
#endif // USING_PTZ
#else // defined(USING_N938)
#define CMD_SET_SYSTEM_RESET 202
#define CMD_SET_SYSTEM_RESET2 203
#define CMD_SET_485_EN1 302
#define CMD_SET_3V3_PWR_EN 132
#define CMD_SET_UART0_EN 361
#define CMD_SET_485_EN0 301
#define CMD_SET_NETWORK_POWER_EN 362
#define CMD_SET_485_EN3 304
#define CMD_SET_485_EN2 303
#define CMD_SET_SPI_POWER 129
// #define CMD_SET_5V_EN 363
#define CMD_SDCARD_DETECT_EN 364
#define CMD_SET_PIC1_POWER 494
#define CMD_SET_OTHER_POWER 493
#define CMD_SET_ANGLE_POWER 492
#define CMD_SET_PULL_POWER 491
#define CMD_SET_WTH_POWER 490
#define CMD_SET_485_EN4 305
#define CMD_LED_CTRL 365
#define CMD_BD_EN 366
#define CMD_ADC_EN 367
#define CMD_SPI2SERIAL_POWER_EN 368
#define CMD_RS485_3V3_EN 369
// Others
#define CMD_SET_485_EN_STATE 131
#define CMD_SET_OTG_STATE 107
#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112
#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117
#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_INIT_STATUS 0 // 401
#endif // USING_N938
#define GPIO_NODE_MP "/dev/mtkgpioctrl"
#define MAX_STRING_LEN 32
typedef struct
{
int cmd;
int value;
int result;
long value2;
char str[MAX_STRING_LEN];
}IOT_PARAM;
class GpioControl
{
public:
struct ITEM
{
int cmd;
size_t references;
time_t openTime;
};
private:
static std::mutex m_locker;
static std::vector<ITEM> m_items;
static bool m_cameraPowerStatus;
static std::mutex m_gpioLocker;
protected:
static size_t turnOnImpl(const IOT_PARAM& param);
static size_t turnOffImpl(const IOT_PARAM& param);
public:
// Power
static size_t TurnOn(int cmd);
static size_t TurnOn(const std::vector<int>& cmds);
static size_t TurnOff(int cmd, uint32_t delayedCloseTime = 0);
static size_t TurnOff(const std::vector<int>& cmds, uint32_t delayedCloseTime = 0);
static size_t TurnOff(const std::vector<std::pair<int, uint32_t> >& cmds);
static size_t TurnOffImmediately(int cmd);
static bool SetCamerastatus(int cmd, bool status);
static bool GetCamerastatus();
static bool GetSelftestStatus(time_t wait_time);
static time_t GetSelfTestRemain(time_t wait_time);
public:
static void setInt(int cmd, int value);
static int getInt(int cmd);
static void setLong(int cmd, long value);
@ -218,95 +61,17 @@ public:
static void setOtgState(bool on)
{
on ? TurnOn(CMD_SET_OTG_STATE) : TurnOff(CMD_SET_OTG_STATE);
setInt(CMD_SET_OTG_STATE, on ? 1 : 0);
}
static bool getOtgState()
{
#ifndef USING_N938
return getInt(CMD_GET_OTG_STATE) != 0;
#else
return false;
#endif
}
static void setCam3V3Enable(bool enabled, uint32_t delayedCloseTime)
{
#ifdef USING_PTZ
enabled ? TurnOn(CMD_SET_3V3_PWR_EN) : TurnOff(CMD_SET_3V3_PWR_EN, delayedCloseTime);
#else
enabled ? TurnOn(CMD_SET_3V3_PWR_EN) : TurnOff(CMD_SET_3V3_PWR_EN, delayedCloseTime);
#endif
return getInt(CMD_SET_OTG_STATE) != 0;
}
static void setCam3V3Enable(bool enabled)
{
#ifdef USING_PTZ
enabled ? TurnOn(CMD_SET_3V3_PWR_EN) : TurnOff(CMD_SET_3V3_PWR_EN);
#else
enabled ? TurnOn(CMD_SET_3V3_PWR_EN) : TurnOff(CMD_SET_3V3_PWR_EN);
#endif
}
static void setBeeOn(bool z)
{
#ifndef USING_N938
#ifndef USING_PTZ
z ? TurnOn(CMD_SET_PWM_BEE_STATE) : TurnOff(CMD_SET_PWM_BEE_STATE);
#endif
#endif
}
static void setJidianqiState(bool z) {
#ifndef USING_N938
#ifndef USING_PTZ
z ? TurnOn(CMD_SET_ALM_MODE) : TurnOff(CMD_SET_ALM_MODE);
#endif
#endif
}
static void setSpiPower(bool on) {
on ? TurnOn(CMD_SET_SPI_POWER) : TurnOff(CMD_SET_SPI_POWER);
if (on)
{
std::this_thread::sleep_for(std::chrono::milliseconds(40));
}
}
static void setRS485Enable(bool z, uint32_t delayedCloseTime)
{
#ifndef USING_N938
#ifdef USING_PTZ
z ? TurnOn(CMD_SET_485_ENABLE) : TurnOff(CMD_SET_485_ENABLE, delayedCloseTime);
#else
z ? TurnOn(CMD_SET_485_EN_STATE) : TurnOff(CMD_SET_485_EN_STATE, delayedCloseTime);
#endif
#endif
}
static void set12VEnable(bool z, uint32_t delayedCloseTime)
{
#ifndef USING_N938
z ? TurnOn(CMD_SET_12V_EN_STATE) : TurnOff(CMD_SET_12V_EN_STATE, delayedCloseTime);
#endif
}
static void setRS485Enable(bool z)
{
#ifndef USING_N938
#ifdef USING_PTZ
z ? TurnOn(CMD_SET_485_ENABLE) : TurnOff(CMD_SET_485_ENABLE);
#else
z ? TurnOn(CMD_SET_485_EN_STATE) : TurnOff(CMD_SET_485_EN_STATE);
#endif
#endif
}
static void set12VEnable(bool z)
{
#ifndef USING_N938
z ? TurnOn(CMD_SET_12V_EN_STATE) : TurnOff(CMD_SET_12V_EN_STATE);
#endif
setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
}
static void reboot()
@ -314,378 +79,100 @@ public:
setInt(CMD_SET_SYSTEM_RESET, 1);
}
static void reboot2()
{
setInt(CMD_SET_SYSTEM_RESET2, 1);
}
static void setLightAdc(int i)
{
#ifndef USING_N938
#ifdef USING_PTZ
setInt(CMD_SET_LIGHT1_RESISTOR_ENABLE, i);
#else
setInt(CMD_SET_LIGHT_ADC, i);
#endif
#endif
}
static int getLightAdc()
{
#ifndef USING_N938
#ifdef USING_PTZ
return getInt(CMD_SET_LIGHT1_RESISTOR_ENABLE);
#else
return getInt(CMD_GET_LIGHT_ADC);
#endif
#else
return -1;
#endif
}
static int getChargingVoltage()
{
#ifndef USING_N938
return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE);
#else
return -1;
#endif
return getInt(CMD_GET_CHARGING_VOL_STATE);
}
#if 0
static int getChargingShuntVoltage()
{
#ifndef USING_N938
return getInt(CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE);
#else
return -1;
#endif
}
#endif
static int getChargingBusVoltage() {
return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE);
}
#if 0
static int getChargingPower() {
#ifndef USING_N938
return getInt(CMD_GET_CHARGING_POWER_STATE);
#else
return -1;
#endif
}
static int getChargingCurrent() {
#ifndef USING_N938
return getInt(CMD_GET_CHARGING_CURRENT_STATE);
#else
return -1;
#endif
}
#endif
static int getBatteryVoltage() {
return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE);
return getInt(CMD_GET_BAT_VOL_STATE);
}
#if 0
static int getBatteryShuntVoltage() {
#ifndef USING_N938
return getInt(CMD_GET_BAT_SHUNT_VOLTAGE_STATE);
#else
return -1;
#endif
}
#endif
static int getBatteryBusVoltage() {
return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE);
}
#if 0
static int getBatteryPower() {
#ifndef USING_N938
return getInt(CMD_GET_BAT_POWER_STATE);
#else
return -1;
#endif
}
static int getBatteryCurrent() {
#ifndef USING_N938
return getInt(CMD_GET_BAT_CURRENT_STATE);
#else
return -1;
#endif
}
#endif
static void set485WriteMode() {
#if 0
setInt(CMD_SET_485_STATE, 1);
#endif
}
static void set485ReadMode() {
#if 0
setInt(CMD_SET_485_STATE, 0);
#endif
}
static void setSpiMode(int i) {
#ifndef USING_N938
setInt(CMD_SET_SPI_MODE, i);
#endif
}
static void setSpiBitsPerWord(int i) {
#ifndef USING_N938
setInt(CMD_SET_SPI_BITS_PER_WORD, i);
#endif
}
static void setSpiMaxSpeedHz(long j) {
#ifndef USING_N938
setLong(CMD_SET_SPI_MAXSPEEDHZ, j);
#endif
}
};
class PowerControl
{
public:
PowerControl(int cmd1) : m_delayCloseTime(0)
{
m_cmds.resize(1, cmd1);
TurnOn();
}
PowerControl(const std::vector<int>& cmds) : m_delayCloseTime(0)
{
m_cmds = cmds;
TurnOn();
}
PowerControl(int cmd1, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(1, cmd1);
TurnOn();
}
PowerControl(int cmd1, int cmd2, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(2, cmd1);
m_cmds[1] = cmd2;
TurnOn();
}
PowerControl(int cmd1, int cmd2, int cmd3, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(3, cmd1);
m_cmds[1] = cmd2;
m_cmds[2] = cmd3;
TurnOn();
}
PowerControl(int cmd1, int cmd2, int cmd3, int cmd4, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(4, cmd1);
m_cmds[1] = cmd2;
m_cmds[2] = cmd3;
m_cmds[3] = cmd4;
TurnOn();
}
PowerControl(int cmd1, int cmd2, int cmd3, int cmd4, int cmd5, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(5, cmd1);
m_cmds[1] = cmd2;
m_cmds[2] = cmd3;
m_cmds[3] = cmd4;
m_cmds[4] = cmd5;
TurnOn();
}
PowerControl(int cmd1, int cmd2, int cmd3, int cmd4, int cmd5, int cmd6, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(6, cmd1);
m_cmds[1] = cmd2;
m_cmds[2] = cmd3;
m_cmds[3] = cmd4;
m_cmds[4] = cmd5;
m_cmds[5] = cmd6;
TurnOn();
static void setBeeOn(bool z) {
setInt(CMD_SET_PWM_BEE_STATE, z ? 1 : 0);
}
PowerControl(int cmd1, int cmd2, int cmd3, int cmd4, int cmd5, int cmd6, int cmd7, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(7, cmd1);
m_cmds[1] = cmd2;
m_cmds[2] = cmd3;
m_cmds[3] = cmd4;
m_cmds[4] = cmd5;
m_cmds[5] = cmd6;
m_cmds[6] = cmd7;
TurnOn();
}
PowerControl(int cmd1, int cmd2, int cmd3, int cmd4, int cmd5, int cmd6, int cmd7, int cmd8, uint32_t closeDelayTime) : m_delayCloseTime(closeDelayTime)
{
m_cmds.resize(8, cmd1);
m_cmds[1] = cmd2;
m_cmds[2] = cmd3;
m_cmds[3] = cmd4;
m_cmds[4] = cmd5;
m_cmds[5] = cmd6;
m_cmds[6] = cmd7;
m_cmds[7] = cmd8;
TurnOn();
}
virtual ~PowerControl()
{
GpioControl::TurnOff(m_cmds, m_delayCloseTime);
#if !defined(NDEBUG) && defined(OUTPUT_DBG_INFO)
std::string status = GetStatus();
XYLOG(XYLOG_SEVERITY_INFO, "PWR After TurnOff %s, DelayCloseTime=%u", status.c_str(), m_delayCloseTime);
#endif
}
#if !defined(NDEBUG) && defined(OUTPUT_DBG_INFO)
std::string GetStatus()
{
std::string result;
for (auto it = m_cmds.cbegin(); it != m_cmds.cend(); ++it)
{
if (*it == 0)
{
continue;
}
result += std::to_string(*it) + "=" + std::to_string(GpioControl::getInt(*it)) + " ";
}
return result;
}
#endif // #if !defined(NDEBUG) && defined(OUTPUT_DBG_INFO)
protected:
void TurnOn()
{
#if !defined(NDEBUG) && defined(OUTPUT_DBG_INFO)
// std::string status = GetStatus();
// XYLOG(XYLOG_SEVERITY_INFO, "PWR Before TurnOn %s", status.c_str());
#endif
GpioControl::TurnOn(m_cmds);
static void setJidianqiState(bool z) {
setInt(CMD_SET_ALM_MODE, z ? 1 : 0);
}
protected:
std::vector<int> m_cmds;
uint32_t m_delayCloseTime;
};
class CameraPowerCtrl : public PowerControl
{
public:
CameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(0, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_3V3_PWR_EN, closeDelayTime)
#else // USING_PTZ
PowerControl(CMD_SET_3V3_PWR_EN, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
static void setSpiPower(bool on) {
setInt(CMD_SET_SPI_POWER, on ? 1 : 0);
}
};
class NetCameraPowerCtrl : public PowerControl
{
public:
NetCameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_12V_EN_STATE, closeDelayTime)
#else // USING_PTZ
// MicroPhoto
PowerControl(CMD_SET_12V_EN_STATE, CMD_SET_485_EN_STATE, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
static void setRS485Enable(bool z) {
setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
}
};
class PlzCameraPowerCtrl : public PowerControl
{
public:
PlzCameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_3V3_PWR_EN, CMD_SET_OTG_STATE, CMD_SET_485_ENABLE, CMD_SET_PTZ_PWR_ENABLE, CMD_SET_12V_EN_STATE, CMD_SET_100M_SWITCH_PWR_ENABLE, closeDelayTime)
#else // USING_PTZ
PowerControl(CMD_SET_OTG_STATE, CMD_SET_12V_EN_STATE, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
}
};
class EthernetPowerCtrl : public PowerControl
{
public:
EthernetPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_OTG_STATE, CMD_SET_NETWORK_POWER_EN, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
// PowerControl(CMD_SET_3V3_PWR_EN, CMD_SET_OTG_STATE, CMD_SET_5V_PWR_ENABLE, CMD_SET_100M_ENABLE, CMD_SET_100M_SWITCH_PWR_ENABLE, closeDelayTime)
PowerControl(CMD_SET_3V3_PWR_EN, CMD_SET_OTG_STATE, CMD_SET_100M_ENABLE, closeDelayTime)
#else // USING_PTZ
// Micro Photo
PowerControl(CMD_SET_OTG_STATE, CMD_SET_485_EN_STATE/* Only for wp6*/, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
}
};
class UsbCameraPowerCtrl : public PowerControl
{
public:
UsbCameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_OTG_STATE, CMD_SET_NETWORK_POWER_EN, CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_PTZ_PWR_ENABLE, CMD_SET_100M_ENABLE, CMD_SET_100M_SWITCH_PWR_ENABLE, CMD_SET_12V_EN_STATE, closeDelayTime)
#else // USING_PTZ
PowerControl(CMD_SET_OTG_STATE, CMD_SET_12V_EN_STATE, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
static void set12VEnable(bool z) {
setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
}
};
class SerialCameraPowerCtrl : public PowerControl
{
public:
SerialCameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_SPI_POWER, CMD_SPI2SERIAL_POWER_EN, CMD_RS485_3V3_EN, CMD_SET_PIC1_POWER, CMD_SET_485_EN4, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_12V_EN_STATE, CMD_SET_485_ENABLE, CMD_SET_3V3_PWR_EN, CMD_SET_SPI_POWER, CMD_SET_PTZ_PWR_ENABLE, closeDelayTime)
#else // USING_PTZ
PowerControl(CMD_SET_12V_EN_STATE, CMD_SET_3V3_PWR_EN, CMD_SET_SPI_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
}
};
#endif //MICROPHOTO_GPIOCONTROL_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -13,7 +13,6 @@
#include <atomic>
#include <filesystem>
#include <thread>
#include <memory>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraError.h>
@ -28,11 +27,6 @@
#include <opencv2/opencv.hpp>
#include <android/bitmap.h>
#include <android/multinetwork.h>
#include "SensorsProtocol.h"
#include "PtzController.h"
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "error", __VA_ARGS__))
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "debug", __VA_ARGS__))
@ -155,132 +149,64 @@ void MatToBitmap(JNIEnv *env, cv::Mat& mat, jobject& bitmap) {
}
#endif
class PowerControl;
class VendorCtrl;
class Streaming;
struct STREAMING_CONTEXT
{
std::shared_ptr<Streaming> stream;
std::shared_ptr<PowerControl> powerCtrl;
std::shared_ptr<PowerControl> ethernetPowerCtrl;
};
class CPhoneDevice : public IDevice
{
public:
friend PtzController;
struct NETWORK
{
std::string iface;
std::string ip;
std::string netmask;
std::string gateway;
};
class CPhoneCamera : public NdkCamera
{
class CPhoneCamera : public NdkCamera {
public:
CPhoneCamera(CPhoneDevice* dev, int32_t width, int32_t height, const NdkCamera::CAMERA_PARAMS& params);
virtual ~CPhoneCamera();
virtual bool on_image(cv::Mat rgb);
virtual bool on_image(cv::Mat& rgb);
virtual void on_error(const std::string& msg);
virtual void onDisconnected(ACameraDevice* device);
virtual bool onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, uint32_t duration, std::vector<std::vector<uint8_t> >& frames);
virtual bool onOneCapture(std::shared_ptr<ACameraMetadata> characteristics, std::shared_ptr<ACameraMetadata> results, uint32_t ldr, uint32_t duration, cv::Mat rgb);
virtual bool onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, uint32_t duration, std::vector<std::shared_ptr<AImage> >& frames);
protected:
CPhoneDevice* m_dev;
};
class CJpegCamera : public CPhoneCamera
{
public:
CJpegCamera(CPhoneDevice* dev, int32_t width, int32_t height, const std::string& path, const NdkCamera::CAMERA_PARAMS& params);
virtual void onImageAvailable(AImageReader* reader);
virtual int32_t getOutputFormat() const;
virtual bool onOneCapture(std::shared_ptr<ACameraMetadata> characteristics, std::shared_ptr<ACameraMetadata> results, uint32_t ldr, uint32_t duration, cv::Mat rgb);
virtual bool onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, uint32_t duration, std::vector<std::vector<uint8_t> >& frames);
virtual bool onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, uint32_t duration, std::vector<std::shared_ptr<AImage> >& frames);
protected:
std::string m_path;
};
struct TIMER_CONTEXT
{
CPhoneDevice* device;
unsigned int timerType;
uint64_t times;
unsigned long times;
void* data;
uint64_t expectedTimes;
uint64_t uid;
unsigned long expectedTimes;
unsigned long uid;
};
CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, uint64_t activeNetHandle, unsigned int versionCode, const std::string& nativeLibDir);
CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId, unsigned int versionCode);
virtual ~CPhoneDevice();
virtual void SetListener(IListener* listener);
virtual void SetRecognizationCfg(const CFG_RECOGNIZATION* pRecognizationCfg);
virtual bool BindNetwork(int sock);
virtual bool SelfTest(std::string& result);
virtual bool UpdateTime(time_t ts);
virtual bool UpdateSchedules();
virtual bool QuerySystemProperties(map<string, string>& properties);
virtual bool InstallAPP(const std::string& path, unsigned int delayedTime);
virtual bool Reboot(int resetType, bool manually, const std::string& reason, uint32_t timeout = 1000);
virtual bool Reboot(int resetType);
virtual bool EnableGPS(bool enabled);
virtual int QueryBattaryVoltage(int timesForAvg, int* isCharging);
virtual uint32_t QueryLdr();
virtual float QueryBattaryVoltage(int timesForAvg, bool* isCharging);
virtual bool RequestPosition();
virtual timer_uid_t RegisterHeartbeat(unsigned int timerType, unsigned int timeout, time_t tsForNextPhoto);
virtual bool TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector<OSD_INFO>& osds, const std::string& path);
virtual bool CloseCamera();
virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout, void* data, uint64_t times = 1);
virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout, void* data, unsigned long times = 0);
virtual bool UnregisterTimer(timer_uid_t uid);
virtual uint64_t RequestWakelock(uint64_t timeout);
virtual bool ReleaseWakelock(uint64_t wakelock);
virtual std::string GetVersion() const;
virtual int GetWData(WEATHER_INFO *weatherInfo, D_SENSOR_PARAM *sensorParam);
virtual int GetIceData(ICE_INFO *iceInfo, ICE_TAIL *icetail, D_SENSOR_PARAM *sensorParam);
virtual bool OpenSensors(int sensortype);
virtual bool CloseSensors(int sensortype, uint32_t delayedCloseTime);
virtual bool OpenPTZSensors(uint32_t sec);
virtual bool ClosePTZSensors(uint32_t delayedCloseTime);
virtual bool GetPTZSensorsStatus(time_t waittime);
virtual bool GetCameraStatus();
virtual void CameraCtrl(unsigned short waitTime, unsigned short delayTime, unsigned char channel, int cmdidx, unsigned char presetno, const char *serfile, unsigned int baud, int addr);
virtual int GetSerialPhoto(int devno, D_IMAGE_DEF *photo);
virtual void InitSerialComm(D_SENSOR_PARAM *sensorParam, char *filedir,const char *logpath);
bool LoadNetworkInfo();
virtual unsigned long RequestWakelock(unsigned long timeout);
virtual bool ReleaseWakelock(unsigned long wakelock);
bool GetNextScheduleItem(uint32_t tsBasedZero, uint32_t scheduleTime, vector<uint32_t>& items);
void UpdatePosition(double lon, double lat, double radius, time_t ts);
bool OnVideoReady(bool photoOrVideo, bool result, const char* path, unsigned int photoId);
bool OnCaptureReady(bool photoOrVideo, bool result, cv::Mat mat, unsigned int photoId);
bool OnVideoReady(bool result, const char* path, unsigned int photoId);
void UpdateSignalLevel(int signalLevel);
void UpdateTfCardPath(const std::string& tfCardPath)
{
m_tfCardPath = tfCardPath;
}
void SetBuildTime(time_t buildTime)
{
mBuildTime = buildTime;
}
void UpdateSimcard(const std::string& simcard);
void UpdateNetwork(net_handle_t nethandle, bool available, bool defaultOrEthernet, bool& changed);
net_handle_t GetEthnetHandle() const;
VendorCtrl* MakeVendorCtrl(int vendor, uint8_t channel, const std::string& ip, const std::string& userName, const std::string& password, net_handle_t netHandle, bool syncTime);
protected:
@ -289,11 +215,7 @@ protected:
bool SendBroadcastMessage(std::string action, int value);
// bool MatchCaptureSizeRequest(ACameraManager *cameraManager, const char *selectedCameraId, unsigned int width, unsigned int height, uint32_t cameraOrientation_,
bool TakePhotoWithNetCamera(const IDevice::PHOTO_INFO& localPhotoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool TakeVideoWithNetCamera(const IDevice::PHOTO_INFO& localPhotoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool StartPushStreaming(const IDevice::PHOTO_INFO& localPhotoInfo, const std::string& url, const std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool PostProcessPhoto(const PHOTO_INFO& photoInfo, const vector<IDevice::OSD_INFO>& osds, const std::string& path, const std::string& cameraInfo, cv::Mat mat, time_t takingTime);
inline bool TakePhotoCb(int res, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime, const std::vector<IDevice::RECOG_OBJECT>& objects) const
inline bool TakePhotoCb(bool res, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime, const std::vector<IDevice::RECOG_OBJECT>& objects) const
{
if (m_listener != NULL)
{
@ -302,83 +224,45 @@ protected:
return false;
}
inline bool TakePhotoCb(int result, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime) const
{
if (m_listener != NULL)
{
std::vector<IDevice::RECOG_OBJECT> objects;
return m_listener->OnPhotoTaken(result, photoInfo, path, photoTime, objects);
}
return false;
}
inline bool TakePTZPhotoCb(int result, const IDevice::PHOTO_INFO& photoInfo) const
inline bool TakePhotoCb(bool res, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime) const
{
if (m_listener != NULL)
{
std::vector<IDevice::RECOG_OBJECT> objects;
return m_listener->OnPTZPhotoTaken(result, photoInfo);
}
return false;
}
inline bool GetPhotoSerialsParamCb(SerialsPhotoParam &param) const
{
if (m_listener != NULL)
{
return m_listener->OnPhotoSerialsParamGet(param);
return m_listener->OnPhotoTaken(res, photoInfo, path, photoTime, objects);
}
return false;
}
void QueryFlowInfo(std::map<std::string, std::string>& powerInfo);
void QueryPowerInfo(std::map<std::string, std::string>& powerInfo);
std::string QueryCpuTemperature();
bool OnImageReady(cv::Mat mat);
bool onOneCapture(std::shared_ptr<ACameraMetadata> characteristics, std::shared_ptr<ACameraMetadata> results, uint32_t ldr, uint32_t duration, cv::Mat rgb);
bool onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, uint32_t duration, std::vector<std::vector<uint8_t> >& frames);
bool onBurstCapture(std::shared_ptr<ACameraMetadata> characteristics, std::vector<std::shared_ptr<ACameraMetadata> >& results, uint32_t ldr, uint32_t duration, std::vector<std::shared_ptr<AImage> >& frames);
bool OnImageReady(cv::Mat& mat);
void onError(const std::string& msg);
void onDisconnected(ACameraDevice* device);
void CloseCamera2(CPhoneCamera* camera, unsigned int photoId, unsigned char cameraType);
void CloseCamera2(CPhoneCamera* camera, unsigned int photoId, bool turnOffOtg);
void TurnOnCameraPower(JNIEnv* env);
void TurnOffCameraPower(JNIEnv* env);
void TurnOnOtg(JNIEnv* env);
void TurnOffOtg(JNIEnv* env);
static void handleSignal(int sig, siginfo_t *si, void *uc);
bool RegisterHandlerForSignal(int sig);
void static handleTimer(union sigval v);
void handleTimerImpl(TIMER_CONTEXT* context);
void static handleRebootTimer(union sigval v);
// void handleRebootTimerImpl();
void RestartApp(int rebootType, long timeout, const std::string& reason);
int QueryBatteryVoltage(int retries);
int CallExecv(int rotation, int frontCamera, const std::string& outputPath, const std::vector<std::string>& images);
void SetStaticIp(const std::string& iface, const std::string& ip, const std::string& netmask, const std::string& gateway);
void ConvertDngToPng(const std::string& dngPath, const std::string& pngPath);
void SetStaticIp();
void ShutdownEthernet();
int ExecuteCommand(const std::string& cmd);
static std::string BuildCaptureResultInfo(ACameraMetadata* result, uint32_t ldr, uint32_t duration, bool burst);
protected:
mutable std::mutex m_devLocker;
std::mutex m_devLocker;
JavaVM* m_vm;
jobject m_javaService;
std::string m_appPath;
std::string m_tfCardPath;
std::string m_nativeLibraryDir;
NETWORK* m_network;
net_handle_t m_defNetHandle;
net_handle_t m_ethnetHandle;
jmethodID mRegisterHeartbeatMid;
jmethodID mUpdateCaptureScheduleMid;
@ -388,32 +272,24 @@ protected:
jmethodID mRequestWakelockMid;
jmethodID mReleaseWakelockMid;
jmethodID mGetFlowInfoMid;
jmethodID mGetSystemInfoMid;
jmethodID mRebootMid;
jmethodID mInstallAppMid;
jmethodID mEnableGpsMid;
jmethodID mRequestPositionMid;
jmethodID mExecHdrplusMid;
jmethodID mSetStaticIpMid;
jmethodID mExecuteCmdMid;
jmethodID mConvertDngToPngMid;
jmethodID mCallSysCameraMid;
std::string mPath;
IDevice::PHOTO_INFO mPhotoInfo;
vector<IDevice::OSD_INFO> mOsds;
IListener* m_listener;
const CFG_RECOGNIZATION* m_pRecognizationCfg;
bool mAIInitialized;
unsigned int mNetId;
unsigned int mVersionCode;
time_t mBuildTime;
atomic_ullong m_timerUidFeed;
atomic_ullong m_wakelockIdFeed;
atomic_ullong m_uniqueIdFeed;
atomic_ulong m_timerUidFeed;
atomic_ulong m_wakelockIdFeed;
std::map<IDevice::timer_uid_t, TIMER_CONTEXT*> mTimers;
mutable CPhoneCamera* mCamera;
@ -421,33 +297,15 @@ protected:
time_t mHeartbeatStartTime;
unsigned int mHeartbeatDuration;
long mCameraPowerCount;
long mOtgCount;
std::thread m_threadClose;
std::shared_ptr<PowerControl> m_powerCtrlPtr;
uint32_t m_ethernetFailures;
int m_signalLevel;
time_t m_signalLevelUpdateTime;
std::string m_simcard;
mutable std::mutex m_cameraLocker;
time_t m_lastTime;
std::atomic<bool> m_shouldStopWaiting;
std::atomic<bool> m_isSelfTesting{false};
IDevice::ICE_TAIL m_tempData;
mutable std::mutex m_dataLocker;
mutable std::mutex m_collectDataLocker;
std::condition_variable m_CollectDatacv;
std::atomic<bool> m_collecting;
unsigned long long localDelayTime;
std::map<uint8_t, STREAMING_CONTEXT > m_streamings;
PtzController* m_ptzController;
};

@ -0,0 +1,912 @@
#include "TerminalDevice.h"
/*
* Copyright 2018 The Android Open Source Project
*
* 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.
*
*/
#define LOG_TAG "CameraTestHelpers"
#include "PhoneDevice2.h"
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
// #include <opencv2/objdetect.hpp>
// #include <opencv2/features2d.hpp>
// #include <opencv2/core/types.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <android/log.h>
#include <AndroidHelper.h>
extern bool GetJniEnv(JavaVM *vm, JNIEnv **env, bool& didAttachThread);
// This value is 2 ^ 18 - 1, and is used to clamp the RGB values before their
// ranges
// are normalized to eight bits.
static const int kMaxChannelValue = 262143;
static inline uint32_t YUV2RGB(int nY, int nU, int nV) {
nY -= 16;
nU -= 128;
nV -= 128;
if (nY < 0) nY = 0;
// This is the floating point equivalent. We do the conversion in integer
// because some Android devices do not have floating point in hardware.
// nR = (int)(1.164 * nY + 1.596 * nV);
// nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU);
// nB = (int)(1.164 * nY + 2.018 * nU);
int nR = (int)(1192 * nY + 1634 * nV);
int nG = (int)(1192 * nY - 833 * nV - 400 * nU);
int nB = (int)(1192 * nY + 2066 * nU);
nR = std::min(kMaxChannelValue, std::max(0, nR));
nG = std::min(kMaxChannelValue, std::max(0, nG));
nB = std::min(kMaxChannelValue, std::max(0, nB));
nR = (nR >> 10) & 0xff;
nG = (nG >> 10) & 0xff;
nB = (nB >> 10) & 0xff;
return 0xff000000 | (nR << 16) | (nG << 8) | nB;
}
CPhoneDevice2::CPhoneDevice2(JavaVM* vm, jobject service)
{
m_vm = vm;
JNIEnv* env = NULL;
bool attached = false;
bool res = GetJniEnv(m_vm, &env, attached);
if (!res)
{
ALOGE("Failed to get JNI Env");
}
m_javaService = env->NewGlobalRef(service);
jclass classService = env->GetObjectClass(m_javaService);
mRegisterTimerMid = env->GetMethodID(classService, "registerTimer", "(JI)Z");
mRegisterHeartbeatMid = env->GetMethodID(classService, "registerHeartbeatTimer", "(I)V");
mUnregisterTimerMid = env->GetMethodID(classService, "unregisterTimer", "(J)Z");
mUpdateTimeMid = env->GetMethodID(classService, "updateTime", "(J)Z");
env->DeleteLocalRef(classService);
if (attached)
{
vm->DetachCurrentThread();
}
m_timerUidFeed = time(NULL);
presentRotation_ = 0;
}
CPhoneDevice2::~CPhoneDevice2()
{
JNIEnv* env = NULL;
bool attached = false;
bool res = GetJniEnv(m_vm, &env, attached);
if (!res)
{
ALOGE("Failed to get JNI Env");
}
env->DeleteGlobalRef(m_javaService);
if (attached)
{
m_vm->DetachCurrentThread();
}
m_javaService = NULL;
}
void CPhoneDevice2::SetListener(IListener* listener)
{
m_listener = listener;
}
bool CPhoneDevice2::UpdateTime(time_t ts)
{
JNIEnv* env = NULL;
jboolean ret = JNI_FALSE;
bool attached = false;
bool res = GetJniEnv(m_vm, &env, attached);
if (!res)
{
ALOGE("Failed to get JNI Env");
return false;
}
jlong timeInMillis = ((jlong)ts) * 1000;
ret = env->CallBooleanMethod(m_javaService, mUpdateTimeMid, timeInMillis);
if (attached)
{
m_vm->DetachCurrentThread();
}
return (ret == JNI_TRUE);
}
bool CPhoneDevice2::Reboot()
{
return false;
}
IDevice::timer_uid_t CPhoneDevice2::RegisterTimer(unsigned int timerType, unsigned int timeout)
{
IDevice::timer_uid_t uid = m_timerUidFeed.fetch_add(1);
ALOGI("NDK RegTimer: uid=%lld Type=%u timeout=%u", uid, timerType, timeout);
JNIEnv* env = NULL;
jboolean ret = JNI_FALSE;
bool attached = false;
bool res = GetJniEnv(m_vm, &env, attached);
if (!res)
{
ALOGE("Failed to get JNI Env");
return 0;
}
ret = env->CallBooleanMethod(m_javaService, mRegisterTimerMid, (jlong)uid, (jint)timeout);
if (attached)
{
m_vm->DetachCurrentThread();
}
if (ret == JNI_TRUE)
{
unsigned long val = timerType;
mTimers.insert(mTimers.end(), std::pair<IDevice::timer_uid_t, unsigned long>(uid, val));
return uid;
}
return 0;
}
bool CPhoneDevice2::UnregisterTimer(IDevice::timer_uid_t uid)
{
JNIEnv* env = NULL;
jboolean ret = JNI_FALSE;
bool attached = false;
bool res = GetJniEnv(m_vm, &env, attached);
if (!res)
{
ALOGE("Failed to get JNI Env");
return false;
}
ret = env->CallBooleanMethod(m_javaService, mUnregisterTimerMid, (jlong)uid);
if (attached)
{
m_vm->DetachCurrentThread();
}
if (ret == JNI_TRUE)
{
mTimers.erase(uid);
return true;
}
return false;
}
bool CPhoneDevice2::FireTimer(timer_uid_t uid)
{
std::map<IDevice::timer_uid_t, unsigned long>::iterator it = mTimers.find(uid);
if (it == mTimers.end())
{
return false;
}
unsigned long timerType = it->second & 0xFFFFFFFF;
unsigned long times = (it->second & 0xFFFFFFFF00000000) >> 32;
times++;
if (timerType != 100)
{
int aa = 0;
}
it->second = timerType | (times << 32);
if (m_listener == NULL)
{
return false;
}
m_listener->OnTimeout(uid, timerType, NULL, times);
return true;
}
IDevice::timer_uid_t CPhoneDevice2::RegisterHeartbeat(unsigned int timerType, unsigned int timeout)
{
IDevice::timer_uid_t uid = m_timerUidFeed.fetch_add(1);
JNIEnv* env = NULL;
jboolean ret = JNI_FALSE;
bool attached = false;
bool res = GetJniEnv(m_vm, &env, attached);
if (!res)
{
ALOGE("Failed to get JNI Env");
return 0;
}
env->CallVoidMethod(m_javaService, mRegisterHeartbeatMid, (jint)timeout);
if (attached)
{
m_vm->DetachCurrentThread();
}
return uid;
}
bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector<OSD_INFO>& osds, const string& path)
{
ALOGI("TAKE_PHOTO: CH=%u PR=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset);
mPhotoInfo = photoInfo;
mPath = path;
mDisplayDimension = DisplayDimension(photoInfo.width, photoInfo.height);
ALOGE("Image Buffer Size: %d", photoInfo.width * photoInfo.height * 4);
imageBuffer_ = (uint8_t*)malloc(photoInfo.width * photoInfo.height * 4);
AASSERT(imageBuffer_ != nullptr, "Failed to allocate imageBuffer_");
int cameraId = (int)photoInfo.channel - 1;
ACameraIdList *cameraIdList = NULL;
ACameraMetadata *cameraMetadata = NULL;
const char *selectedCameraId = NULL;
camera_status_t camera_status = ACAMERA_OK;
ACameraManager *cameraManager = ACameraManager_create();
camera_status = ACameraManager_getCameraIdList(cameraManager, &cameraIdList);
if (camera_status != ACAMERA_OK) {
ALOGI("Failed to get camera id list (reason: %d)\n", camera_status);
TakePhotoCb(false, photoInfo, path, 0);
return false;
}
if (cameraIdList->numCameras < 1 ) {
ALOGI("No camera device detected.\n");
TakePhotoCb(false, photoInfo, path, 0);
return false;
}
if (cameraIdList->numCameras <= cameraId ) {
ALOGI("No required camera device %d detected.\n", cameraId);
TakePhotoCb(false, photoInfo, path, 0);
return false;
}
selectedCameraId = cameraIdList->cameraIds[cameraId];
ALOGI("Trying to open Camera2 (id: %s, num of camera : %d)\n", selectedCameraId,
cameraIdList->numCameras);
camera_status = ACameraManager_getCameraCharacteristics(cameraManager, selectedCameraId,
&cameraMetadata);
if (camera_status != ACAMERA_OK) {
ALOGI("Failed to get camera meta data of ID:%s\n", selectedCameraId);
}
ACameraMetadata_const_entry face, orientation;
camera_status = ACameraMetadata_getConstEntry(cameraMetadata, ACAMERA_LENS_FACING, &face);
uint32_t cameraFacing_ = static_cast<int32_t>(face.data.u8[0]);
if (cameraFacing_ == ACAMERA_LENS_FACING_FRONT)
{
int aa = 0;
}
camera_status = ACameraMetadata_getConstEntry(cameraMetadata, ACAMERA_SENSOR_ORIENTATION, &orientation);
ALOGI("====Current SENSOR_ORIENTATION: %8d", orientation.data.i32[0]);
uint32_t cameraOrientation_ = orientation.data.i32[0];
if (cameraOrientation_ == 90 || cameraOrientation_ == 270)
{
mDisplayDimension.Flip();
}
ImageFormat resCap = {(int32_t)photoInfo.width, (int32_t)photoInfo.height, AIMAGE_FORMAT_YUV_420_888};
MatchCaptureSizeRequest(cameraManager, selectedCameraId, photoInfo.width, photoInfo.height, cameraOrientation_, &resCap);
deviceStateCallbacks.onDisconnected = camera_device_on_disconnected;
deviceStateCallbacks.onError = camera_device_on_error;
camera_status = ACameraManager_openCamera(cameraManager, selectedCameraId,
&deviceStateCallbacks, &cameraDevice);
if (camera_status != ACAMERA_OK) {
ALOGI("Failed to open camera device (id: %s)\n", selectedCameraId);
}
camera_status = ACameraDevice_createCaptureRequest(cameraDevice, TEMPLATE_STILL_CAPTURE/*TEMPLATE_PREVIEW*/,
&captureRequest);
if (camera_status != ACAMERA_OK) {
ALOGI("Failed to create preview capture request (id: %s)\n", selectedCameraId);
}
ACaptureSessionOutputContainer_create(&captureSessionOutputContainer);
captureSessionStateCallbacks.onReady = capture_session_on_ready;
captureSessionStateCallbacks.onActive = capture_session_on_active;
captureSessionStateCallbacks.onClosed = capture_session_on_closed;
ACameraMetadata_free(cameraMetadata);
ACameraManager_deleteCameraIdList(cameraIdList);
ACameraManager_delete(cameraManager);
media_status_t status;
// status = AImageReader_new(1920, 1080, AIMAGE_FORMAT_YUV_420_888, 5, &mAImageReader);
status = AImageReader_new(resCap.width, resCap.height, resCap.format, 5, &mAImageReader);
if (status != AMEDIA_OK)
{
ALOGI("AImageReader_new error\n");
TakePhotoCb(false, photoInfo, path, 0);
return false;
}
AImageReader_ImageListener listener{
.context = this,
.onImageAvailable = OnImageCallback,
};
AImageReader_setImageListener(mAImageReader, &listener);
//ANativeWindow *mNativeWindow;
status = AImageReader_getWindow(mAImageReader, &theNativeWindow);
if (status != AMEDIA_OK)
{
ALOGI("AImageReader_getWindow error\n");
TakePhotoCb(false, photoInfo, path, 0);
return false;
}
ALOGI("Surface is prepared in %p.\n", theNativeWindow);
// theNativeWindow
ACameraOutputTarget_create(theNativeWindow, &cameraOutputTarget);
ACaptureRequest_addTarget(captureRequest, cameraOutputTarget);
ACaptureSessionOutput_create(theNativeWindow, &sessionOutput);
ACaptureSessionOutputContainer_add(captureSessionOutputContainer, sessionOutput);
ACameraDevice_createCaptureSession(cameraDevice, captureSessionOutputContainer,
&captureSessionStateCallbacks, &captureSession);
// ACameraCaptureSession_setRepeatingRequest(captureSession, NULL, 1, &captureRequest, NULL);
ACameraCaptureSession_capture(captureSession, NULL, 1, &captureRequest, NULL);
ALOGI("Surface is prepared in here.\n");
return true;
}
ACameraCaptureSession_stateCallbacks* CPhoneDevice2::GetSessionListener()
{
static ACameraCaptureSession_stateCallbacks sessionListener = {
.context = this,
.onClosed = CPhoneDevice2::capture_session_on_closed,
.onReady = CPhoneDevice2::capture_session_on_ready,
.onActive = CPhoneDevice2::capture_session_on_active,
};
return &sessionListener;
}
void CPhoneDevice2::ImageCallback(AImageReader *reader)
{
bool res = false;
AImage *image = nullptr;
media_status_t status = AImageReader_acquireNextImage(reader, &image);
if (status == AMEDIA_OK && image)
{
int32_t srcFormat = -1;
AImage_getFormat(image, &srcFormat);
AASSERT(AIMAGE_FORMAT_YUV_420_888 == srcFormat, "Failed to get format");
int32_t srcPlanes = 0;
AImage_getNumberOfPlanes(image, &srcPlanes);
AASSERT(srcPlanes == 3, "Is not 3 planes");
AImageCropRect srcRect;
AImage_getCropRect(image, &srcRect);
int32_t width = srcRect.right - srcRect.left;
int32_t height = srcRect.bottom - srcRect.top;
// int32_t height = srcRect.right - srcRect.left;
// int32_t width = srcRect.bottom - srcRect.top;
uint8_t *yPixel = nullptr;
uint8_t *uPixel = nullptr;
uint8_t *vPixel = nullptr;
int32_t yLen = 0;
int32_t uLen = 0;
int32_t vLen = 0;
AImage_getPlaneData(image, 0, &yPixel, &yLen);
AImage_getPlaneData(image, 1, &uPixel, &uLen);
AImage_getPlaneData(image, 2, &vPixel, &vLen);
uint8_t * data = new uint8_t[yLen + vLen + uLen];
memcpy(data, yPixel, yLen);
memcpy(data+yLen, vPixel, vLen);
memcpy(data+yLen+vLen, uPixel, uLen);
cv::Mat mYUV = cv::Mat(((height * 3) >> 1), width, CV_8UC1, data);
// cv::cvtColor(mYUV, _yuv_rgb_img, cv::COLOR_YUV2RGB_NV21, 3);
// cv::Mat mYUV = cv::Mat(height, yStride, CV_8UC4, data);
cv::Mat _yuv_rgb_img(height, width, CV_8UC4), _yuv_gray_img;
cv::cvtColor(mYUV, _yuv_rgb_img, cv::COLOR_YUV2RGB_NV21, 3);
cv::rotate(_yuv_rgb_img, _yuv_rgb_img, cv::ROTATE_180);
// cv::Mat rgbMat(height, width, CV_8UC3);
// 通过cv::cvtColor将yuv420转换为rgb格式
// cvtColor(_yuv_rgb_img, rgbMat, cv::COLOR_YUV2RGB_I420);
// cv::Mat mat = cv::Mat(buffer.height, buffer.stride, CV_8UC4, buffer.bits);
const char *str = "OSD";
putText(_yuv_rgb_img, str, cv::Point(50, 50), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 0), 4,cv::LINE_AA);
putText(_yuv_rgb_img, str, cv::Point(50, 50), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 2,cv::LINE_AA);
vector <int> compression_params;
compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
compression_params.push_back(80);
res = cv::imwrite(mPath.c_str(), _yuv_rgb_img, compression_params);
// ANativeWindow_unlockAndPost(theNativeWindow);
if (res)
{
int aa = 0;
}
// res = WriteFile(image, GetFileName() + ".org.jpg");
AImage_delete(image);
// delete pThis;
TakePhotoCb(res, mPhotoInfo, mPath, time(NULL));
}
}
void CPhoneDevice2::OnImageCallback(void *ctx, AImageReader *reader)
{
CPhoneDevice2* pThis = reinterpret_cast<CPhoneDevice2*>(ctx);
if (pThis != NULL)
{
pThis->ImageCallback(reader);
}
}
bool CPhoneDevice2::WriteFile(AImage *image, const string& path)
{
int planeCount = 0;
media_status_t status = AImage_getNumberOfPlanes(image, &planeCount);
ALOGI("Info: getNumberOfPlanes() planeCount = %d", planeCount);
if (!(status == AMEDIA_OK && planeCount == 1))
{
ALOGE("Error: getNumberOfPlanes() planeCount = %d", planeCount);
return false;
}
uint8_t *data = nullptr;
int len = 0;
AImage_getPlaneData(image, 0, &data, &len);
bool res = false;
FILE *file = fopen(path.c_str(), "wb");
if (file && data && len)
{
fwrite(data, 1, len, file);
fclose(file);
ALOGI("Capture: %s", path.c_str());
res = true;
}
else
{
if (file)
fclose(file);
}
return res;
}
bool CPhoneDevice2::WriteFile(CPhoneDevice2* pThis, AImage *image)
{
return pThis->WriteFile(image, pThis->GetFileName());
}
std::string CPhoneDevice2::GetFileName() const
{
return mPath;
}
/*
const char *selectedCameraId = NULL;
ACameraManager *cameraManager = ACameraManager_create();
*/
bool CPhoneDevice2::MatchCaptureSizeRequest(ACameraManager *cameraManager, const char *selectedCameraId, unsigned int width, unsigned int height, uint32_t cameraOrientation_,
ImageFormat* resCap) {
DisplayDimension disp(resCap->width,resCap->height);
if (cameraOrientation_ == 90 || cameraOrientation_ == 270) {
disp.Flip();
}
ACameraMetadata* metadata;
camera_status_t camera_status = ACAMERA_OK;
camera_status = ACameraManager_getCameraCharacteristics(cameraManager, selectedCameraId, &metadata);
ACameraMetadata_const_entry entry;
camera_status = ACameraMetadata_getConstEntry(metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
// format of the data: format, width, height, input?, type int32
bool foundIt = false;
DisplayDimension foundRes(16384, 16384);
DisplayDimension maxJPG(0, 0);
for (int i = 0; i < entry.count; i += 4) {
int32_t input = entry.data.i32[i + 3];
int32_t format = entry.data.i32[i + 0];
if (input) continue;
if (format == AIMAGE_FORMAT_YUV_420_888 || format == AIMAGE_FORMAT_JPEG) {
DisplayDimension res(entry.data.i32[i + 1], entry.data.i32[i + 2]);
ALOGI("Camera Resolution: %d x %d fmt=%d", res.width(), res.height(), format);
if (!disp.IsSameRatio(res)) continue;
if (format == AIMAGE_FORMAT_YUV_420_888 && res > disp) {
foundIt = true;
foundRes = res;
} else if (format == AIMAGE_FORMAT_JPEG && res > maxJPG) {
maxJPG = res;
}
}
}
if (foundIt) {
// resView->width = foundRes.org_width();
// resView->height = foundRes.org_height();
resCap->width = foundRes.org_width();
resCap->height = foundRes.org_height();
} else {
ALOGI("Did not find any compatible camera resolution, taking 640x480");
resCap->width = disp.org_width();
resCap->height = disp.org_height();
// *resCap = *resView;
}
// resView->format = AIMAGE_FORMAT_YUV_420_888;
// resCap->format = AIMAGE_FORMAT_JPEG;
return foundIt;
}
/**
* Convert yuv image inside AImage into ANativeWindow_Buffer
* ANativeWindow_Buffer format is guaranteed to be
* WINDOW_FORMAT_RGBX_8888
* WINDOW_FORMAT_RGBA_8888
* @param buf a {@link ANativeWindow_Buffer } instance, destination of
* image conversion
* @param image a {@link AImage} instance, source of image conversion.
* it will be deleted via {@link AImage_delete}
*/
bool CPhoneDevice2::DisplayImage(ANativeWindow_Buffer *buf, AImage *image) {
AASSERT(buf->format == WINDOW_FORMAT_RGBX_8888 ||
buf->format == WINDOW_FORMAT_RGBA_8888,
"Not supported buffer format");
int32_t srcFormat = -1;
AImage_getFormat(image, &srcFormat);
AASSERT(AIMAGE_FORMAT_YUV_420_888 == srcFormat, "Failed to get format");
int32_t srcPlanes = 0;
AImage_getNumberOfPlanes(image, &srcPlanes);
AASSERT(srcPlanes == 3, "Is not 3 planes");
switch (presentRotation_) {
case 0:
PresentImage(buf, image);
break;
case 90:
PresentImage90(buf, image);
break;
case 180:
PresentImage180(buf, image);
break;
case 270:
PresentImage270(buf, image);
break;
default:
AASSERT(0, "NOT recognized display rotation: %d", presentRotation_);
}
AImage_delete(image);
image = nullptr;
return true;
}
/*
* PresentImage()
* Converting yuv to RGB
* No rotation: (x,y) --> (x, y)
* Refer to:
* https://mathbits.com/MathBits/TISection/Geometry/Transformations2.htm
*/
void CPhoneDevice2::PresentImage(ANativeWindow_Buffer *buf, AImage *image) {
AImageCropRect srcRect;
AImage_getCropRect(image, &srcRect);
AImage_getPlaneRowStride(image, 0, &yStride);
AImage_getPlaneRowStride(image, 1, &uvStride);
yPixel = imageBuffer_;
AImage_getPlaneData(image, 0, &yPixel, &yLen);
vPixel = imageBuffer_ + yLen;
AImage_getPlaneData(image, 1, &vPixel, &vLen);
uPixel = imageBuffer_ + yLen + vLen;
AImage_getPlaneData(image, 2, &uPixel, &uLen);
AImage_getPlanePixelStride(image, 1, &uvPixelStride);
int32_t rowStride;
AImage_getPlaneRowStride(image, 0, &rowStride);
int32_t height = std::min(buf->height, (srcRect.bottom - srcRect.top));
int32_t width = std::min(buf->width, (srcRect.right - srcRect.left));
uint32_t *out = static_cast<uint32_t *>(buf->bits);
for (int32_t y = 0; y < height; y++) {
const uint8_t *pY = yPixel + yStride * (y + srcRect.top) + srcRect.left;
int32_t uv_row_start = uvStride * ((y + srcRect.top) >> 1);
const uint8_t *pU = uPixel + uv_row_start + (srcRect.left >> 1);
const uint8_t *pV = vPixel + uv_row_start + (srcRect.left >> 1);
for (int32_t x = 0; x < width; x++) {
const int32_t uv_offset = (x >> 1) * uvPixelStride;
out[x] = YUV2RGB(pY[x], pU[uv_offset], pV[uv_offset]);
}
out += buf->stride;
}
}
/*
* PresentImage90()
* Converting YUV to RGB
* Rotation image anti-clockwise 90 degree -- (x, y) --> (-y, x)
*/
void CPhoneDevice2::PresentImage90(ANativeWindow_Buffer *buf, AImage *image) {
AImageCropRect srcRect;
AImage_getCropRect(image, &srcRect);
AImage_getPlaneRowStride(image, 0, &yStride);
AImage_getPlaneRowStride(image, 1, &uvStride);
yPixel = imageBuffer_;
AImage_getPlaneData(image, 0, &yPixel, &yLen);
vPixel = imageBuffer_ + yLen;
AImage_getPlaneData(image, 1, &vPixel, &vLen);
uPixel = imageBuffer_ + yLen + vLen;
AImage_getPlaneData(image, 2, &uPixel, &uLen);
AImage_getPlanePixelStride(image, 1, &uvPixelStride);
int32_t height = std::min(buf->width, (srcRect.bottom - srcRect.top));
int32_t width = std::min(buf->height, (srcRect.right - srcRect.left));
uint32_t *out = static_cast<uint32_t *>(buf->bits);
out += height - 1;
for (int32_t y = 0; y < height; y++) {
const uint8_t *pY = yPixel + yStride * (y + srcRect.top) + srcRect.left;
int32_t uv_row_start = uvStride * ((y + srcRect.top) >> 1);
const uint8_t *pU = uPixel + uv_row_start + (srcRect.left >> 1);
const uint8_t *pV = vPixel + uv_row_start + (srcRect.left >> 1);
for (int32_t x = 0; x < width; x++) {
const int32_t uv_offset = (x >> 1) * uvPixelStride;
// [x, y]--> [-y, x]
int testb = pU[uv_offset];
int testc = pV[uv_offset];
int testA = pY[x];
out[x * buf->stride] = YUV2RGB(testA, testb, testc);
}
out -= 1; // move to the next column
}
}
/*
* PresentImage180()
* Converting yuv to RGB
* Rotate image 180 degree: (x, y) --> (-x, -y)
*/
void CPhoneDevice2::PresentImage180(ANativeWindow_Buffer *buf, AImage *image) {
AImageCropRect srcRect;
AImage_getCropRect(image, &srcRect);
AImage_getPlaneRowStride(image, 0, &yStride);
AImage_getPlaneRowStride(image, 1, &uvStride);
yPixel = imageBuffer_;
AImage_getPlaneData(image, 0, &yPixel, &yLen);
vPixel = imageBuffer_ + yLen;
AImage_getPlaneData(image, 1, &vPixel, &vLen);
uPixel = imageBuffer_ + yLen + vLen;
AImage_getPlaneData(image, 2, &uPixel, &uLen);
AImage_getPlanePixelStride(image, 1, &uvPixelStride);
int32_t height = std::min(buf->height, (srcRect.bottom - srcRect.top));
int32_t width = std::min(buf->width, (srcRect.right - srcRect.left));
uint32_t *out = static_cast<uint32_t *>(buf->bits);
out += (height - 1) * buf->stride;
for (int32_t y = 0; y < height; y++) {
const uint8_t *pY = yPixel + yStride * (y + srcRect.top) + srcRect.left;
int32_t uv_row_start = uvStride * ((y + srcRect.top) >> 1);
const uint8_t *pU = uPixel + uv_row_start + (srcRect.left >> 1);
const uint8_t *pV = vPixel + uv_row_start + (srcRect.left >> 1);
for (int32_t x = 0; x < width; x++) {
const int32_t uv_offset = (x >> 1) * uvPixelStride;
// mirror image since we are using front camera
out[width - 1 - x] = YUV2RGB(pY[x], pU[uv_offset], pV[uv_offset]);
// out[x] = YUV2RGB(pY[x], pU[uv_offset], pV[uv_offset]);
}
out -= buf->stride;
}
}
/*
* PresentImage270()
* Converting image from YUV to RGB
* Rotate Image counter-clockwise 270 degree: (x, y) --> (y, x)
*/
void CPhoneDevice2::PresentImage270(ANativeWindow_Buffer *buf, AImage *image) {
AImageCropRect srcRect;
AImage_getCropRect(image, &srcRect);
AImage_getPlaneRowStride(image, 0, &yStride);
AImage_getPlaneRowStride(image, 1, &uvStride);
yPixel = imageBuffer_;
AImage_getPlaneData(image, 0, &yPixel, &yLen);
vPixel = imageBuffer_ + yLen;
AImage_getPlaneData(image, 1, &vPixel, &vLen);
uPixel = imageBuffer_ + yLen + vLen;
AImage_getPlaneData(image, 2, &uPixel, &uLen);
AImage_getPlanePixelStride(image, 1, &uvPixelStride);
int32_t height = std::min(buf->width, (srcRect.bottom - srcRect.top));
int32_t width = std::min(buf->height, (srcRect.right - srcRect.left));
uint32_t *out = static_cast<uint32_t *>(buf->bits);
for (int32_t y = 0; y < height; y++) {
const uint8_t *pY = yPixel + yStride * (y + srcRect.top) + srcRect.left;
int32_t uv_row_start = uvStride * ((y + srcRect.top) >> 1);
const uint8_t *pU = uPixel + uv_row_start + (srcRect.left >> 1);
const uint8_t *pV = vPixel + uv_row_start + (srcRect.left >> 1);
for (int32_t x = 0; x < width; x++) {
const int32_t uv_offset = (x >> 1) * uvPixelStride;
int testb = pU[uv_offset];
int testc = pV[uv_offset];
int testA = pY[x];
out[(width - 1 - x) * buf->stride] =
YUV2RGB(testA, testb, testc);
}
out += 1; // move to the next column
}
}
/*
bool CPhoneDevice2::SendBroadcastMessage(String16 action, int value)
{
TM_INFO_LOG("sendBroadcastMessage(): Action: %s, Value: %d ", action.string(), value);
sp <IServiceManager> sm = defaultServiceManager();
sp <IBinder> am = sm->getService(String16("activity"));
if (am != NULL) {
Parcel data, reply;
data.writeInterfaceToken(String16("android.app.IActivityManager"));
data.writeStrongBinder(NULL);
// intent begin
data.writeString16(action); // action
data.writeInt32(0); // URI data type
data.writeString16(NULL, 0); // type
data.writeInt32(0); // flags
data.writeString16(NULL, 0); // package name
data.writeString16(NULL, 0); // component name
data.writeInt32(0); // source bound - size
data.writeInt32(0); // categories - size
data.writeInt32(0); // selector - size
data.writeInt32(0); // clipData - size
data.writeInt32(-2); // contentUserHint: -2 -> UserHandle.USER_CURRENT
data.writeInt32(-1); // bundle extras length
data.writeInt32(0x4C444E42); // 'B' 'N' 'D' 'L'
int oldPos = data.dataPosition();
data.writeInt32(1); // size
// data.writeInt32(0); // VAL_STRING, need to remove because of analyze common intent
data.writeString16(String16("type"));
data.writeInt32(1); // VAL_INTEGER
data.writeInt32(value);
int newPos = data.dataPosition();
data.setDataPosition(oldPos - 8);
data.writeInt32(newPos - oldPos); // refill bundle extras length
data.setDataPosition(newPos);
// intent end
data.writeString16(NULL, 0); // resolvedType
data.writeStrongBinder(NULL); // resultTo
data.writeInt32(0); // resultCode
data.writeString16(NULL, 0); // resultData
data.writeInt32(-1); // resultExtras
data.writeString16(NULL, 0); // permission
data.writeInt32(0); // appOp
data.writeInt32(-1); // option
data.writeInt32(1); // serialized: != 0 -> ordered
data.writeInt32(0); // sticky
data.writeInt32(-2); // userId: -2 -> UserHandle.USER_CURRENT
status_t ret = am->transact(IBinder::FIRST_CALL_TRANSACTION + 13, data,
&reply); // BROADCAST_INTENT_TRANSACTION
if (ret == NO_ERROR) {
int exceptionCode = reply.readExceptionCode();
if (exceptionCode) {
TM_INFO_LOG("sendBroadcastMessage(%s) caught exception %d\n",
action.string(), exceptionCode);
return false;
}
} else {
return false;
}
} else {
TM_INFO_LOG("getService() couldn't find activity service!\n");
return false;
}
return true;
}
*/
void CPhoneDevice2::camera_device_on_disconnected(void *context, ACameraDevice *device)
{
ALOGI("Camera(id: %s) is diconnected.\n", ACameraDevice_getId(device));
CPhoneDevice2* pThis = (CPhoneDevice2*)context;
// delete pThis;
}
void CPhoneDevice2::camera_device_on_error(void *context, ACameraDevice *device, int error)
{
ALOGI("Error(code: %d) on Camera(id: %s).\n", error, ACameraDevice_getId(device));
}
void CPhoneDevice2::capture_session_on_ready(void *context, ACameraCaptureSession *session)
{
ALOGI("Session is ready. %p\n", session);
}
void CPhoneDevice2::capture_session_on_active(void *context, ACameraCaptureSession *session)
{
ALOGI("Session is activated. %p\n", session);
}
void CPhoneDevice2::capture_session_on_closed(void *context, ACameraCaptureSession *session)
{
ALOGI("Session is closed. %p\n", session);
}

@ -0,0 +1,124 @@
#ifndef __PHONE_DEVICE2_H__
#define __PHONE_DEVICE2_H__
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <map>
#include <atomic>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraError.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraMetadataTags.h>
#include <media/NdkImageReader.h>
#include <Client/Device.h>
#include <string>
#include "camera2/Camera2Helper.h"
class CPhoneDevice2 : public IDevice
{
public:
CPhoneDevice2(JavaVM* vm, jobject service);
virtual ~CPhoneDevice2();
virtual void SetListener(IListener* listener);
virtual bool UpdateTime(time_t ts);
virtual bool Reboot();
virtual timer_uid_t RegisterHeartbeat(unsigned int timerType, unsigned int timeout);
virtual bool TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector<OSD_INFO>& osds, const string& path);
virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout);
virtual bool UnregisterTimer(timer_uid_t uid);
virtual bool FireTimer(timer_uid_t uid);
protected:
ACameraCaptureSession_stateCallbacks *GetSessionListener();
std::string GetFileName() const;
bool SendBroadcastMessage(std::string action, int value);
bool MatchCaptureSizeRequest(ACameraManager *cameraManager, const char *selectedCameraId, unsigned int width, unsigned int height, uint32_t cameraOrientation_,
ImageFormat* resCap);
bool DisplayImage(ANativeWindow_Buffer* buf, AImage* image);
void PresentImage(ANativeWindow_Buffer* buf, AImage* image);
void PresentImage90(ANativeWindow_Buffer* buf, AImage* image);
void PresentImage180(ANativeWindow_Buffer* buf, AImage* image);
void PresentImage270(ANativeWindow_Buffer* buf, AImage* image);
static void camera_device_on_disconnected(void *context, ACameraDevice *device);
static void camera_device_on_error(void *context, ACameraDevice *device, int error);
static void capture_session_on_ready(void *context, ACameraCaptureSession *session);
static void capture_session_on_active(void *context, ACameraCaptureSession *session);
static void capture_session_on_closed(void *context, ACameraCaptureSession *session);
void ImageCallback(AImageReader *reader);
static void OnImageCallback(void *ctx, AImageReader *reader);
bool WriteFile(AImage *image, const string& path);
static bool WriteFile(CPhoneDevice2* pThis, AImage *image);
inline bool TakePhotoCb(bool res, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime)
{
if (m_listener != NULL)
{
std::vector<IDevice::RECOG_OBJECT> objects;
return m_listener->OnPhotoTaken(res, photoInfo, path, photoTime, objects);
}
return false;
}
protected:
JavaVM* m_vm;
jobject m_javaService;
jmethodID mRegisterTimerMid;
jmethodID mRegisterHeartbeatMid;
jmethodID mUnregisterTimerMid;
jmethodID mUpdateTimeMid;
std::string mPath;
IDevice::PHOTO_INFO mPhotoInfo;
IListener* m_listener;
atomic_ulong m_timerUidFeed;
std::map<IDevice::timer_uid_t, unsigned long> mTimers;
AImageReader *mAImageReader;
ANativeWindow *theNativeWindow;
ACameraDevice *cameraDevice;
ACaptureRequest *captureRequest;
ACameraOutputTarget *cameraOutputTarget;
ACaptureSessionOutput *sessionOutput;
ACaptureSessionOutputContainer *captureSessionOutputContainer;
ACameraCaptureSession *captureSession;
ACameraDevice_StateCallbacks deviceStateCallbacks;
ACameraCaptureSession_stateCallbacks captureSessionStateCallbacks;
DisplayDimension mDisplayDimension;
int32_t presentRotation_;
int32_t imageHeight_;
int32_t imageWidth_;
uint8_t* imageBuffer_;
int32_t yStride, uvStride;
uint8_t *yPixel, *uPixel, *vPixel;
int32_t yLen, uLen, vLen;
int32_t uvPixelStride;
};
#endif // __PHONE_DEVICE2_H__

@ -1,57 +0,0 @@
#ifndef __POSITION_HELPER_H__
#define __POSITION_HELPER_H__
#include <cmath>
#define _USE_MATH_DEFINES
inline double transformLat(double x, double y)
{
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * std::sqrt(std::abs(x));
ret += (20.0 * std::sin(6.0 * x * M_PI) + 20.0 * std::sin(2.0 * x * M_PI)) * 2.0 / 3.0;
ret += (20.0 * std::sin(y * M_PI) + 40.0 * std::sin(y / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (160.0 * std::sin(y / 12.0 * M_PI) + 320 * std::sin(y * M_PI / 30.0)) * 2.0 / 3.0;
return ret;
}
inline double transformLng(double x, double y)
{
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * std::sqrt(std::abs(x));
ret += (20.0 * std::sin(6.0 * x * M_PI) + 20.0 * std::sin(2.0 * x * M_PI)) * 2.0 / 3.0;
ret += (20.0 * std::sin(x * M_PI) + 40.0 * std::sin(x / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (150.0 * std::sin(x / 12.0 * M_PI) + 300.0 * std::sin(x / 30.0 * M_PI)) * 2.0 / 3.0;
return ret;
}
inline void transformPosition(double& lat, double& lng)
{
// 卫星椭球坐标投影到平面地图坐标系的投影因子
#define AXIS 6378245.0
// 椭球的偏心率(a^2 - b^2) / a^2
#define OFFSET 0.00669342162296594323
double dLat = transformLat(lng - 105.0, lat - 35.0);
double dLon = transformLng(lng - 105.0, lat - 35.0);
double radLat = lat / 180.0 * M_PI;
double magic = std::sin(radLat);
magic = 1 - OFFSET * magic * magic;
double sqrtMagic = std::sqrt(magic);
dLat = (dLat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtMagic) * M_PI);
dLon = (dLon * 180.0) / (AXIS / sqrtMagic * std::cos(radLat) * M_PI);
lat += dLat;
lng += dLon;
}
inline bool shouldConvertPosition(double lat, double lon)
{
if (lon < 72.004 || lon > 137.8347)
{
return false;
}
if (lat < 0.8293 || lat > 55.8271)
{
return false;
}
return true;
}
#endif // __POSITION_HELPER_H__

@ -1,462 +0,0 @@
//
// Created by Matthew on 2025/3/5.
//
#include "PtzController.h"
#include "SensorsProtocol.h"
#include "GPIOControl.h"
#include "PhoneDevice.h"
#include "time.h"
#include <memory>
PtzController::PtzController(CPhoneDevice* pPhoneDevice) : m_pPhoneDevice(pPhoneDevice)
{
m_exit = false;
}
void PtzController::Startup()
{
m_thread = std::thread(PtzThreadProc, this);
}
void PtzController::PtzThreadProc(PtzController* pThis)
{
pThis->PtzProc();
}
void PtzController::AddCommand(uint8_t channel, int cmdidx, uint8_t bImageSize, uint8_t preset, const char *serfile, uint32_t baud, int addr)
{
SERIAL_CMD cmd = { 0 };
cmd.channel = channel;
cmd.preset = preset;
cmd.cmdidx = cmdidx;
cmd.bImageSize = bImageSize;
strcpy(cmd.serfile, serfile);
cmd.baud = baud;
cmd.addr = addr;
cmd.ts = time(NULL);
m_locker.lock();
m_cmds.push_back(cmd);
m_locker.unlock();
m_sem.release();
}
void PtzController::AddPhotoCommand(IDevice::PHOTO_INFO& photoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds)
{
IDevice::SerialsPhotoParam param = { "", 0, 0 };
m_pPhoneDevice->GetPhotoSerialsParamCb(param);
SERIAL_CMD cmdPreset = { 0 };
time_t ts = time(NULL);
#if 1
// if (photoInfo.preset != 0 && photoInfo.preset != 0xFF)
{
cmdPreset.ts = photoInfo.selfTestingTime;
cmdPreset.delayTime = photoInfo.closeDelayTime;
cmdPreset.channel = photoInfo.channel;
cmdPreset.channel = photoInfo.preset;
cmdPreset.cmdidx = PHOTO_OPEN_POWER;
strcpy(cmdPreset.serfile, param.serfile);
cmdPreset.baud = param.baud;
cmdPreset.addr = param.addr;
}
#endif
SERIAL_CMD cmd = { 0 };
cmd.ts = ts;
cmd.delayTime = photoInfo.closeDelayTime;
cmd.channel = photoInfo.channel;
cmd.preset = photoInfo.preset;
cmd.cmdidx = Take_Photo;
cmd.bImageSize = photoInfo.resolution;
strcpy(cmd.serfile, param.serfile);
cmd.baud = param.baud;
cmd.addr = param.addr;
PtzPhotoParams* ppp = new PtzPhotoParams(photoInfo, path, osds);
cmd.photoParams.reset(ppp);
// cmd.delayTime;
// uint8_t bImageSize;
// char serfile[128];
// uint32_t baud;
// int addr;
m_locker.lock();
#if 1
if (cmdPreset.cmdidx != 0)
{
m_cmds.push_back(cmdPreset);
}
#endif
m_cmds.push_back(cmd);
m_locker.unlock();
m_sem.release();
m_sem.release();
}
void PtzController::ExitAndWait()
{
m_exit = true;
m_sem.release();
if (m_thread.joinable())
{
m_thread.join();
}
}
void PtzController::PtzProc()
{
PROC_PTZ_STATE state = PTZS_POWER_OFF;
SERIAL_CMD cmd;
PTZ_STATE ptz_state;
bool hasCmd = false;
int i=0;
int closecmd=0;
std::shared_ptr<PowerControl> powerCtrl;
time_t selfTestingStartTime = 0;
time_t selfTestingWaitTime = 0;
time_t PTZ_preset_start_time = 0;
time_t PTZ_preset_wait_time = 0;
time_t close_delay_time = CAMERA_CLOSE_DELAYTIME;
time_t start_delay_time = 0;
time_t auto_delay_time = 0;
time_t auto_wait_time = WAIT_TIME_AUTO_CLOSE;
time_t photo_move_preset_time = 0;
int iwaitime = 0;
while(true)
{
m_sem.acquire();
if (m_exit)
{
break;
}
hasCmd = false;
m_locker.lock();
for (auto it = m_cmds.begin(); it != m_cmds.end(); ++it)
{
if ((state == PTZS_SELF_TESTING) || (PTZS_PHOTO_SELF_TESTING == state))
{
// find first non-taking-photo cmd
if (it->cmdidx != Take_Photo)
{
cmd = *it;
m_cmds.erase(it);
hasCmd = true;
break;
}
}
else
{
cmd = *it;
m_cmds.erase(it);
hasCmd = true;
break;
}
}
m_locker.unlock();
if (!hasCmd)
{
if ((state == PTZS_SELF_TESTING) || (PTZS_PHOTO_SELF_TESTING == state))
{
time_t timeout = time(NULL) - selfTestingStartTime;
if(timeout < 0)
selfTestingStartTime = time(NULL);
if (timeout >= selfTestingWaitTime)
{
XYLOG(XYLOG_SEVERITY_INFO, "超时(%u秒)未收到云台自检结束应答,状态改为空闲!", (uint32_t)timeout);
state = PTZS_IDLE;
m_sem.release();
continue;
}
else
{
//if(timeout >= CAMERA_SELF_TEST_TIME)
{
#ifndef NDEBUG
if (timeout == 1 || ((timeout % 10) == 0))
#endif
{
XYLOG(XYLOG_SEVERITY_INFO, "开始查询云台自检状态timeout=%u秒", (uint32_t)timeout);
}
if(0 == QueryPtzState(&ptz_state, QUERY_PTZ_STATE, cmd.serfile, cmd.baud, cmd.addr))
{
if(0 == ptz_state.ptz_status)
{
XYLOG(XYLOG_SEVERITY_INFO, "收到云台自检结束应答状态改为空闲timeout=%u秒", (uint32_t)timeout);
state = PTZS_IDLE;
m_sem.release();
continue;
}
}
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
m_sem.release();
continue;
}
if(0 == start_delay_time)
{
if(0 == iwaitime)
{
auto_delay_time = time(NULL);
iwaitime += 1;
m_sem.release();
continue;
}
else
{
if(time(NULL) - auto_delay_time < 0)
{
auto_delay_time = time(NULL);
}
if(time(NULL) - auto_delay_time >= auto_wait_time)
{
iwaitime = 0;
XYLOG(XYLOG_SEVERITY_INFO, "摄像机自动上电延时时间超过%u秒准备关闭摄像机", (uint32_t)auto_wait_time);
}
else
{
m_sem.release();
continue;
}
}
}
else
{
if(time(NULL) - start_delay_time < 0)
{/* 防止等待关机期间,其他线程发生对时,改变了系统时间,导致长时间不会关摄像机电源*/
start_delay_time = time(NULL);
}
if(time(NULL) - start_delay_time >= close_delay_time)
{
XYLOG(XYLOG_SEVERITY_INFO, "摄像机空闲时间超过%u秒准备关闭摄像机", (uint32_t)close_delay_time);
}
else
{
m_sem.release();
continue;
}
}
if (state == PTZS_POWER_OFF)
{
closecmd = 0;
XYLOG(XYLOG_SEVERITY_INFO, "自动关机触发,摄像机本来就处于关机状态!");
// Do Nothing
}
else
{
XYLOG(XYLOG_SEVERITY_INFO, "自动关机触发通知云台准备关机state=%d", state);
for(i=0; i<3; i++)
{
if(0 == QueryPtzState(&ptz_state, NOTIFY_PTZ_CLOSE, cmd.serfile, cmd.baud, cmd.addr))
break;
}
powerCtrl.reset();
closecmd = 0;
state = PTZS_POWER_OFF;
XYLOG(XYLOG_SEVERITY_INFO, "自动触发关闭云台电源state=%d", state);
}
start_delay_time = 0;
continue;
}
switch (cmd.cmdidx)
{
case Take_Photo:
{
if (state == PTZS_POWER_OFF)
{
if (!powerCtrl)
{
//powerCtrl = std::make_shared<PlzCameraPowerCtrl>(cmd.photoParams->mPhotoInfo.closeDelayTime);
powerCtrl = std::make_shared<PlzCameraPowerCtrl>(0);
selfTestingStartTime = time(NULL);
selfTestingWaitTime = cmd.photoParams->mPhotoInfo.selfTestingTime;
state = PTZS_PHOTO_SELF_TESTING;
XYLOG(XYLOG_SEVERITY_INFO, "1、收到拍照指令摄像机从关机状态改为自检状态");
m_locker.lock();
m_cmds.insert(m_cmds.begin(), cmd);
m_locker.unlock();
m_sem.release();
continue;
}
}
if(cmd.photoParams->mPhotoInfo.scheduleTime == 0)
{
if(1 == closecmd)
{
XYLOG(XYLOG_SEVERITY_INFO, "3、收到手动拍照指令但同时后续收到关机指令等待拍完照片再关机。state=%d", state);
}
else
{
start_delay_time = time(NULL);
XYLOG(XYLOG_SEVERITY_INFO, "3、收到手动拍照指令state=%d", state);
}
}
else
XYLOG(XYLOG_SEVERITY_INFO, "2、收到自动拍照指令state=%d", state);
state = PTZS_TAKING_PHOTO;
if (cmd.preset != 0 && cmd.preset != 0xFF)
{
CameraPhotoCmd(0, cmd.channel, MOVE_PRESETNO, 0, cmd.preset, cmd.serfile, cmd.baud, cmd.addr);
#if 0
if(START_ONCE_SELF == cmd.preset)
{
selfTestingStartTime = time(NULL);
selfTestingWaitTime = CAMERA_SELF_TEST_TIME;
state = PTZS_SELF_TESTING;
m_sem.release();
XYLOG(XYLOG_SEVERITY_INFO, "拍照调用200号预置点指令摄像机启动一次性自检从拍照状态改为自检状态取消拍照动作设置的自检等待时间%u秒", (uint32_t)selfTestingWaitTime);
break;
}
#endif
PTZ_preset_start_time = time(NULL);
if(START_ONCE_SELF == cmd.preset)
PTZ_preset_wait_time = CAMERA_SELF_TEST_TIME;
else
PTZ_preset_wait_time = MOVE_PRESET_WAIT_TIME;
XYLOG(XYLOG_SEVERITY_INFO, "摄像机拍照前开始调用预置点%ustate=%d", (uint32_t)cmd.preset, state);
for(;;)
{
if(0 == QueryPtzState(&ptz_state, QUERY_PTZ_STATE, cmd.serfile, cmd.baud, cmd.addr))
{
if(0 == ptz_state.ptz_status)
{
XYLOG(XYLOG_SEVERITY_INFO, "摄像机拍照前调用预置点%u收到移动结束应答移动时长=%d秒 state=%d", (uint32_t)cmd.preset, (uint32_t)(time(NULL)-PTZ_preset_start_time), state);
break;
}
}
if(time(NULL) - PTZ_preset_start_time < 0)
{/* 防止等待关机期间,其他线程发生对时,改变了系统时间,导致长时间等待摄像机到达预置点*/
PTZ_preset_start_time = time(NULL);
}
if(time(NULL) - PTZ_preset_start_time >= PTZ_preset_wait_time)
{
XYLOG(XYLOG_SEVERITY_INFO, "摄像机拍照前调用预置点%u摄像机在%u秒内未收到调用预置点结束应答state=%d", (uint32_t)cmd.preset, (uint32_t)PTZ_preset_wait_time, state);
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
photo_move_preset_time = time(NULL);
}
}
if(cmd.photoParams->mPhotoInfo.mediaType == 1)
m_pPhoneDevice->TakeVideoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
else if ((cmd.photoParams->mPhotoInfo.mediaType == XY_MEDIA_TYPE_STREAM || cmd.photoParams->mPhotoInfo.mediaType == XY_MEDIA_TYPE_STREAM_OFF))
{
m_pPhoneDevice->StartPushStreaming(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
}
else
m_pPhoneDevice->TakePhotoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
state = PTZS_IDLE;
}
break;
case PHOTO_OPEN_POWER:
if (state == PTZS_POWER_OFF)
{
if (!powerCtrl)
{
powerCtrl = std::make_shared<PlzCameraPowerCtrl>(0);
selfTestingStartTime = time(NULL);
selfTestingWaitTime = CAMERA_SELF_TEST_TIME;
state = PTZS_PHOTO_SELF_TESTING;
m_sem.release();
XYLOG(XYLOG_SEVERITY_INFO, "收到拍照指令开机,摄像机从关机状态改为自检状态!设置的自检等待时间%u秒", (uint32_t)selfTestingWaitTime);
}
}
else
{
XYLOG(XYLOG_SEVERITY_INFO, "收到拍照指令开机摄像机处于state=%d", state);
}
break;
case OPEN_TOTAL:
if (state == PTZS_POWER_OFF)
{
if (!powerCtrl)
{
powerCtrl = std::make_shared<PlzCameraPowerCtrl>(0);
selfTestingStartTime = time(NULL);
selfTestingWaitTime = CAMERA_SELF_TEST_TIME;
state = PTZS_SELF_TESTING;
m_sem.release();
XYLOG(XYLOG_SEVERITY_INFO, "收到手动开机指令,摄像机从关机状态改为自检状态!设置的自检等待时间%u秒", (uint32_t)selfTestingWaitTime);
}
}
else
{
XYLOG(XYLOG_SEVERITY_INFO, "收到手动开机指令摄像机处于state=%d", state);
}
closecmd = 0;
start_delay_time = time(NULL);
XYLOG(XYLOG_SEVERITY_INFO, "收到手动打开摄像机指令刷新关机计时初始值state=%d", state);
break;
case CLOSE_TOTAL:
if (state == PTZS_POWER_OFF)
{
closecmd = 0;
XYLOG(XYLOG_SEVERITY_INFO, "收到关机指令,摄像机本来就处于关机状态!");
// Do Nothing
}
else if(PTZS_PHOTO_SELF_TESTING == state)
{
closecmd = 1;
XYLOG(XYLOG_SEVERITY_INFO, "在拍照自检过程中收到关机指令取消延时关机转到自动关机处理state=%d", state);
}
else
{
XYLOG(XYLOG_SEVERITY_INFO, "收到关机指令通知云台准备关机state=%d", state);
for(i=0; i<3; i++)
{
if(0 == QueryPtzState(&ptz_state, NOTIFY_PTZ_CLOSE, cmd.serfile, cmd.baud, cmd.addr))
break;
}
closecmd = 0;
powerCtrl.reset();
state = PTZS_POWER_OFF;
XYLOG(XYLOG_SEVERITY_INFO, "关闭云台电源state=%d", state);
}
start_delay_time = 0;
break;
default:
{
if (state == PTZS_POWER_OFF)
{
XYLOG(XYLOG_SEVERITY_INFO, "收到手动控制摄像机指令,摄像机处于关机状态,无法执行!");
CameraPhotoCmd(cmd.ts, cmd.channel, cmd.cmdidx, 0, cmd.preset, cmd.serfile, cmd.baud, cmd.addr);
break;
}
start_delay_time = time(NULL);
XYLOG(XYLOG_SEVERITY_INFO, "收到手动控制摄像机指令刷新关机计时初始值state=%d", state);
if(cmd.ts <= photo_move_preset_time)
{
XYLOG(XYLOG_SEVERITY_INFO, "丢弃拍照调预置点期间收到的控制云台指令,指令时间" FMT_TIME_T ",拍照时间" FMT_TIME_T "state=%d", cmd.ts, photo_move_preset_time, state);
}
else
{
if((MOVE_PRESETNO == cmd.cmdidx) && (START_ONCE_SELF == cmd.preset))
{
selfTestingStartTime = time(NULL);
selfTestingWaitTime = CAMERA_SELF_TEST_TIME;
state = PTZS_SELF_TESTING;
m_sem.release();
XYLOG(XYLOG_SEVERITY_INFO, "收到调用200号预置点指令摄像机启动一次性自检从当前状态改为自检状态设置的自检等待时间%u秒", (uint32_t)selfTestingWaitTime);
}
CameraPhotoCmd(cmd.ts, cmd.channel, cmd.cmdidx, 0, cmd.preset, cmd.serfile, cmd.baud, cmd.addr);
}
}
break;
}
}
}

@ -1,100 +0,0 @@
//
// Created by Matthew on 2025/3/5.
//
#ifndef MICROPHOTO_PTZCONTROLLER_H
#define MICROPHOTO_PTZCONTROLLER_H
#include <Buffer.h>
#include <thread>
#include <vector>
#include <memory>
#include <string>
#include <mutex>
#include <SemaphoreEx.h>
#include <Client/Device.h>
enum PROC_PTZ_STATE
{
PTZS_POWER_OFF = 0,
PTZS_IDLE = 1,
PTZS_SELF_TESTING = 2,
PTZS_MOVING = 3,
PTZS_TAKING_PHOTO = 4,
PTZS_PHOTO_SELF_TESTING = 5,
};
#define CAMERA_SELF_TEST_TIME 150 /* Camera self-test time (excluding PTZ self-test)*/
#define MOVE_PRESET_WAIT_TIME 20 /* Waiting for the maximum time for the PTZ to move to the preset position*/
#define CAMERA_CLOSE_DELAYTIME 360 /* Auto Power-Off Timer Setting After Manual Power-On (for Camera)*/
#define PHOTO_OPEN_POWER 16000
#define WAIT_TIME_AUTO_CLOSE 2 /* In order to automatically capture multiple preset point images at the same time and prevent the camera from self checking every time it takes a picture.*/
class PtzPhotoParams
{
public:
PtzPhotoParams(const IDevice::PHOTO_INFO& photoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds) :
mPhotoInfo(photoInfo), mPath(path), mOsds(osds)
{
}
~PtzPhotoParams()
{
}
IDevice::PHOTO_INFO mPhotoInfo;
std::string mPath;
std::vector<IDevice::OSD_INFO> mOsds;
};
struct SERIAL_CMD
{
uint8_t channel;
uint8_t preset;
time_t ts;
int cmdidx;
uint32_t delayTime;
uint8_t bImageSize;
char serfile[128];
uint32_t baud;
int addr;
std::shared_ptr<PtzPhotoParams> photoParams;
};
class CPhoneDevice;
class PtzController
{
public:
PtzController(CPhoneDevice* pPhoneDevice);
void Startup();
// ();
void AddCommand(uint8_t channel, int cmdidx, uint8_t bImageSize, uint8_t preset, const char *serfile, uint32_t baud, int addr);
void AddPhotoCommand(IDevice::PHOTO_INFO& photoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds);
void ExitAndWait();
protected:
static void PtzThreadProc(PtzController* pThis);
void PtzProc();
protected:
protected:
std::mutex m_locker;
std::vector<SERIAL_CMD> m_cmds;
CSemaphore m_sem;
bool m_exit;
std::thread m_thread;
CPhoneDevice* m_pPhoneDevice;
};
#endif //MICROPHOTO_PTZCONTROLLER_H

File diff suppressed because it is too large Load Diff

@ -2,32 +2,43 @@
// Created by hyz on 2024/6/5.
//
#ifndef __SENSOR_PROTOCOL_H__
#define __SENSOR_PROTOCOL_H__
#ifndef WEATHERCOMM_H
#define WEATHERCOMM_H
#include <string>
#include "GPIOControl.h"
#include "termios.h"
#ifndef LOBYTE
#define LOBYTE(w) ((unsigned char)(w))
#ifndef DWORD
typedef unsigned int DWORD;
#endif
#ifndef HIBYTE
#define HIBYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF))
#ifndef WORD
typedef unsigned short WORD;
#endif
#ifndef LOWORD
#define LOWORD(l) ((uint16_t)(l))
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef HIWORD
#define HIWORD(l) ((uint16_t)((uint32_t)(l) >> 16))
#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_FIELDS_NUM 20 /* BD_NMEA0183单组字符串数据内含数据最大数量*/
#define MAX_SERIAL_DEV_NUM 25 /* 最大接串口传感器数量*/
#define MAX_SERIAL_PORT_NUM 5
#define MAX_DEV_VALUE_NUM 12 /* 一台装置最大的采样值数量*/
@ -39,8 +50,6 @@
#define PELCO_P_PROTOCOL 5 /* 摄像机Pelco_P协议序号*/
#define PELCO_D_PROTOCOL 6 /* 摄像机Pelco_D协议序号*/
#define SERIALCAMERA_PROTOCOL 8 /* 串口摄像机协议序号*/
#define MUTIWEATHER_PROTOCOL 9 /*多合一气象*/
#define NMEA0183_PROTOCOL 10 /* 单一北斗NMEA0183标准协议*/
#define RESERVE2_PROTOCOL 17 /* 备用2协议序号*/
#define RESERVE4_PROTOCOL 19 /* 备用4协议序号*/
#define RESERVE5_PROTOCOL 20 /* 备用5协议序号*/
@ -85,9 +94,9 @@
#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_WIDE 0x00400000 /* 远离物体(1 有效)*/
#define P_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/
#define P_MOVE_DOWN 0x0010001f /* 向下移动镜头(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 有效)*/
@ -97,21 +106,19 @@
#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_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 D_OPEN_TOTAL 0x0009000B /* 打开总电源(1 有效)*/
#define D_OPEN_MODULE_POWER 0x0009000C /* 打开机芯电源(1 有效)*/
/* 摄像机下发命令宏定义*/
#define TAKE_PHOTO 20000 /* 拍照*/
#define SET_BAUD 10000 /* 设置球机波特率*/
#define STOP_CMD 10005 /* 取消或停止指令*/
#define AUTO_SCAN 10006 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/
#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 有效)*/
@ -124,27 +131,34 @@
#define MOVE_RIGHT 10016 /* 向右移动镜头(1 有效)*/
#define MOVE_PRESETNO 10017 // 调用预置点
#define SAVE_PRESETNO 10018 // 设置预置点
#define OPEN_TOTAL 10019 /* 打开总电源(1 有效)*/
#define OPEN_MODULE_POWER 10020 /* 打开机芯电源(1 有效)*/
#define NOTIFY_PTZ_CLOSE 10021 // 通知云台关闭
#define QUERY_PTZ_STATE 10022 // 查询云台状态
#define CLOSE_TOTAL 10040 /* 关闭总电源*/
#define SPEED_DOME_CAMERA 0 /* 球机摄像机*/
#define SERIAL_CAMERA 2 /* 串口摄像机a*/
#define START_ONCE_SELF 200 /* 一次性自检需要的调用的预置点200*/
#define COLLECT_DATA 0 /* 调试使用*/
#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
{
uint8_t PortIdx; // 信息类型
uint16_t MsgType; // 信息类型
BYTE PortIdx; // 信息类型
WORD MsgType; // 信息类型
int MsgLen; // 信息长度
uint8_t MsgData[RECVDATA_MAXLENTH];
u_char MsgData[RECVDATA_MAXLENTH];
} RTUMSG;
typedef struct
@ -162,7 +176,7 @@ typedef struct
typedef struct
{
uint8_t AiState; // 数据标识(-1采样失败0:没有采样1正在采样2采样结束3启动采样
BYTE AiState; // 数据标识(-1采样失败0:没有采样1正在采样2采样结束3启动采样
float EuValue; // 数据工程值
} Data_DEF;
@ -170,7 +184,7 @@ typedef struct
{
int imagelen; // 整个图片大小
int phototime; // 拍照时间
uint8_t presetno; // 拍照预置点
u_char presetno; // 拍照预置点
char photoname[512]; // 图片存储名称和路径
int state;// 标识(-1拍照失败0:没有拍照1正在取图2拍照成功3启动拍照
} IMAGE_DEF;
@ -180,15 +194,15 @@ typedef struct
int imagelen; // 整个图片大小
int imagenum; // 整个图片的总包数
int phototime; // 拍照时间
uint8_t presetno; // 拍照预置点
u_char presetno; // 拍照预置点
char photoname[512]; // 图片存储名称和路径
uint8_t buf[MAX_PHOTO_PACKET_NUM][MAX_PHOTO_FRAME_LEN]; // 图片数据缓存
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 SENSOR_PARAM
typedef struct
{
unsigned int baudrate; /* 波特率*/
int databit; /* 数据位*/
@ -196,13 +210,11 @@ typedef struct SENSOR_PARAM
char parity; /* 校验位*/
char pathname[64]; /* 串口文件名及路径*/
//int commNo; /* 约定的串口序号例如我们PC机上显示的COM1。。。*/
uint8_t SensorsType; /* 传感器类型索引,大于 0*/
u_char SensorsType; /* 传感器类型索引,大于 0*/
int devaddr; /* 装置(传感器)使用的地址*/
uint8_t IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/
uint8_t CameraChannel; /* 像机的通道号*/
uint8_t Phase; /* 传感器所安装相别指拉力和倾角11表示A1....*/
float multiple; /*系数*/
float offset; /*偏移值*/
u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/
u_char CameraChannel; /* 像机的通道号*/
u_char Phase; /* 传感器所安装相别指拉力和倾角11表示A1....*/
} SENSOR_PARAM;
// 需要配置的串口装置参数
@ -214,111 +226,53 @@ typedef struct
char parity; /* 校验位*/
char pathname[64]; /* 串口文件名及路径*/
int commid; /* 串口序号 注意从0开始*/
uint8_t ProtocolIdx; /* 规约索引,大于 0*/
u_char ProtocolIdx; /* 规约索引,大于 0*/
int devaddr; /* 装置使用的地址*/
uint8_t IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/
uint8_t CameraChannel; /* 像机的通道号*/
uint8_t Phase; /* 传感器所安装相别指拉力和倾角11表示A1....*/
u_char IsNoInsta; /* 装置没有安装或者已经坏了(1:正常, 0:无效,坏了或没有安装)*/
u_char CameraChannel; /* 像机的通道号*/
u_char Phase; /* 传感器所安装相别指拉力和倾角11表示A1....*/
} SERIAL_PARAM;
// 云台状态数据
typedef struct
{
uint8_t ptz_process; /* 云台所处过程(1:自检状态;2:调用预置点;3:一般状态;)*/
uint8_t ptz_status; /* 云台当前状态值(0:停止;1:运动;2:机芯未上电;其他:其他错误*/
int presetno; /* 云台所处预置点值*/
float x_coordinate; /* 云台所处位置水平方向坐标*/
float y_coordinate; /* 云台所处位置垂直方向坐标*/
} PTZ_STATE;
/*
$--RMC IDRMC --
2 UTCtime hhmmss.ss UTC
3 status
V=
A=
4 lat ddmm.mmmmm 2
5 uLat N-S-
6 lon dddmm.mmmm
m
3
7 uLon E-W-西
8 spd
9 cog
10 date ddmmyy dd mm yy
11 mv
12 mvE E-W-西
13 mode [1]
14 navStatus V
NMEA 4.1
15 CS 16 $*$**/
// 北斗卫星数据
typedef struct
{
struct tm UTC_time; /* UTC时间*/
int ms_time; /* 毫秒*/
double lat; /* 纬度,原值(前 2 字符表示度,后面的字符表示分)转换后为° */
char uLat; /* 纬度方向N-北S-南*/
double lon; /* 经度,原值(前 3 字符表示度,后面的字符表示分)转换后为°*/
char uLon; /* 经度'E'-东,'W'-西*/
char status; /* 'A'=数据有效 其他字符表示数据无效*/
} BD_GNSS_DATA;
typedef struct
{
int m_iRevStatus; /* */
int m_iRecvLen; /* */
int m_iNeedRevLength; /* */
int iRecvTime; /* */
uint8_t m_au8RecvBuf[RECVDATA_MAXLENTH];/* */
u_char m_au8RecvBuf[RECVDATA_MAXLENTH];/* */
int fd; /* 串口打开的文件句柄*/
uint8_t PollCmd[SENDDATA_MAXLENTH];
u_char PollCmd[SENDDATA_MAXLENTH];
int cmdlen; // 发送缓冲区命令长度
//******************** Poll Cmd ****************************
uint8_t Retry; /* 重试命令次数 */
uint8_t RetryCnt; /* 重试命令计数*/
int64_t RetryTime; /* 重试命令时间 */
int64_t RetryTimeCnt; /* 重试命令时间计数*/
int64_t WaitTime; /* 命令间隔时间 */
int64_t WaitTimeCnt; /* 命令间隔时间计数*/
uint8_t ForceWaitFlag; /* 强制等待标志*/
uint16_t ForceWaitCnt; /* 强制等待计数*/
uint8_t ReSendCmdFlag; /* 重发命令标志 */
uint8_t SendCmdFlag; /* 命令发送标志 */
uint8_t RevCmdFlag; /* 命令正常接收标志*/
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; /* 命令正常接收标志*/
//**********************************************************
int64_t lsendtime; /* 命令发送绝对时间计时(毫秒)*/
int cameraaddr; /* 摄像机地址*/
int SerialCmdidx; /* 正在使用的串口发送命令的命令序号(-1:表示没有命令发送)
使*/
PHOTO_DEF image; /* 临时存储图片数据*/
int64_t FirstCmdTimeCnt; /* 串口读取数据起始时间*/
PTZ_STATE ptz_state;
int sendptzstatecmd; // 查询命令次数控制
BD_GNSS_DATA bd_data;
LONG lsendtime; /* 命令发送绝对时间计时(毫秒)*/
} SIO_PARAM_SERIAL_DEF;
typedef const struct
{
//char *account; // 命令说明
char *cmd_name; // 命令名称
int (*recv_process)(SIO_PARAM_SERIAL_DEF *); /* urc数据处理*/
}BD_NMEA0183_PROC_FUNC;
//串口相关装置所有参数集中定义
typedef struct
{
//******************** 端口基本信息 ************************
uint8_t IsNeedSerial; /* 是否需要使用串口通讯*/
u_char IsNeedSerial; /* 是否需要使用串口通讯*/
int CmdWaitTime; /* 没有使用*/
uint8_t UseSerialidx; /* 使用的串口序号*/
u_char UseSerialidx; /* 使用的串口序号*/
int SerialCmdidx; /* 正在使用的串口发送命令的命令序号(-1:表示没有命令发送)
使*/
int enrecvtime; /* 发送加密命令后接收到应答计时*/
int64_t FirstCmdTimeCnt; /* 串口读取数据起始时间*/
uint8_t nextcmd; /* 第二次发送读取气象雨量命令 */
uint8_t SameTypeDevIdx; /* 相同类型装置顺序排列序号(从0开始)*/
uint8_t uOpenPowerFlag; /* 传感器上电标志(0:不需要打开; 1:需要打开)*/
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]; /* 传感器采样值*/
@ -327,17 +281,17 @@ typedef struct
//串口相关装置所有参数集中定义
typedef struct
{
uint8_t clcyesampling; /* 正在进行采样(0:没有进行采样;1:正在进行采样;)*/
uint8_t camerauseserial; /* 摄像机使用那个串口*/
uint32_t PtzCmdType; /* 云台指令类型*/
u_char clcyesampling; /* 正在进行采样(0:没有进行采样;1:正在进行采样;)*/
u_char camerauseserial; /* 摄像机使用那个串口*/
DWORD PtzCmdType; /* 云台指令类型*/
int usecameradevidx; /* 有像机指令需要执行*/
/* 执行指令的装置序号(-1:表示没有需要执行的指令;)*/
int SendStopPtzCmdTimeCnt; /* 发送云台停止指令*/
uint8_t serialstatus[MAX_SERIAL_PORT_NUM]; /* 串口是否可以使用状态分别对应串口1、2、3*/
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表示没有装置需要通讯)*/
uint8_t IsReadWireTem; /* 是否在开始读取测温数据(0:表示没有;1:是)*/
u_char IsReadWireTem; /* 是否在开始读取测温数据(0:表示没有;1:是)*/
//int proruntime; /* 程序运行时间*/
int IsSleep; /* 是否使程序休眠(1:不休眠;2:休眠)*/
int tempsamplingstartime; /* 测温启动距离采样启动时间间隔*/
@ -358,16 +312,16 @@ typedef struct
int sendphotocmdcnt; /* 一次拍照过程中发送拍照指令计数*/
int photographtime; /* 图片拍摄的时间*/
int iLastGetPhotoNo; /* 设置串口摄像机参数时暂存拍照命令序号*/
uint8_t bImageSize; /* 用于临时存储接收上层命令的图片大小*/
uint8_t presetno; /* 用于临时存储接收上层命令的预置点*/
u_char bImageSize; /* 用于临时存储接收上层命令的图片大小*/
u_char presetno; /* 用于临时存储接收上层命令的预置点*/
char filedir[512]; /* 用于摄像机拍照之后暂时存放的路径*/
#endif
uint8_t errorPhotoNoCnt; /* 串口摄像机拍照时回应错误包号计数(如:召第6包回应第3包)*/
uint8_t RephotographCnt; /* 串口摄像机重拍计数(只在读照片数据应答出错时才重拍)*/
u_char errorPhotoNoCnt; /* 串口摄像机拍照时回应错误包号计数(如:召第6包回应第3包)*/
u_char RephotographCnt; /* 串口摄像机重拍计数(只在读照片数据应答出错时才重拍)*/
} SRDT_DEF;
static void PortDataProcess( void );
static int64_t get_msec();
static LONG get_msec();
int serial_port_comm();
static int weather_comm(SERIAL_PARAM weatherport);
@ -380,7 +334,6 @@ static void setCam3V3Enable(bool enabled);
// 串口相关的所有函数定义
/* 打开串口电源*/
void Gm_OpenSerialPower();
uint8_t getdevtype(int devno);
// 打开传感器电源
void Gm_OpenSensorsPower();
@ -392,16 +345,15 @@ void Gm_OpenSerialPort(int devidx);
// 关闭串口通讯
void Gm_CloseSerialPort();
void DBG_LOG(int commid, char flag, const char* format, ...);
int SaveLogTofile(int commid, const char *szbuf);
void DebugLog(int commid, char *szbuf, char flag);
int SaveLogTofile(int commid, char *szbuf);
// 功能说明:串口发送数据 返回实际发送的字节数
int GM_SerialComSend(const unsigned char * cSendBuf, size_t nSendLen, int commid);
void Gm_InitSerialComm(SENSOR_PARAM *sensorParam, const char *filedir,const char *log);
int GM_SerialComSend(const unsigned char * cSendBuf, LONG nSendLen, int commid);
void Gm_InitSerialComm(SENSOR_PARAM *sensorParam, char *filedir);
// 启动串口通讯
void GM_StartSerialComm();
// 启动使用串口拍照
int GM_StartSerialCameraPhoto(int phototime, unsigned char channel, int cmdidx, unsigned char bImageSize, unsigned char presetno, const char *serfile, unsigned int baud, int addr);
void GM_StartSerialCameraPhoto(BYTE channel, int cmdidx);
void delete_old_files(const char *path, int days);
// 串口轮询通讯定时器
@ -417,12 +369,12 @@ int GM_CloseTimer();
void testComm();
void Gm_InitSerialComm_Test();
// 串口接收数据处理
void SerialDataProcess(int devidx, uint8_t *buf, int len);
void SerialDataProcess(int devidx, u_char *buf, int len);
void CameraRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, uint8_t *buf, int len);
void CameraRecvData(int commid, u_char *buf, int len);
// 串口摄像机数据处理
void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial);
void CameraPhotoPortDataProcess( int port);
// 发送命令
void SendCmdFormPollCmdBuf( int port );
@ -431,29 +383,29 @@ void SendCmdFormPollCmdBuf( int port );
void ClearCmdAllFlag(int commid);
// 下发串口拍照指令控制
int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam);
int FindNextCameraPhotoCommand(int devidx);
// 生成 CameraPhoto命令
void MakeCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint8_t cmdidx, int OneParam, uint16_t TwoParam, uint8_t Threep, int phototime);
void MakeCameraPhotoCommand( int portno, BYTE cmdidx, int OneParam, WORD TwoParam, BYTE Threep, int phototime);
// 清除命令缓冲区
void ClearCmdFormPollCmdBuf(int port);
// 准备发送云台指令
int Gm_CtrlPtzCmd(SIO_PARAM_SERIAL_DEF *pPortParam, uint32_t ptzcmd);
int Gm_CtrlPtzCmd(u_char channel, DWORD ptzcmd);
// 发送转动摄像机云台命令定时器
int Gm_Camera_Timer();
// 生成 PELCO_P 命令 *
void Gm_SendPelco_pCommand( uint32_t cmdtype);
void Gm_SendPelco_pCommand( DWORD cmdtype);
// 计算Pelco_p校验
uint8_t Gm_Pelco_pXORCheck( uint8_t *msg, int len );
BYTE Gm_Pelco_pXORCheck( BYTE *msg, int len );
// 生成 PELCO_D 命令 *
void Gm_SendPelco_DCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint32_t cmdtype);
void Gm_SendPelco_DCommand( DWORD cmdtype);
// 计算Pelco_D校验
uint8_t Gm_Pelco_DCheck( uint8_t *msg, int len );
BYTE Gm_Pelco_DCheck( BYTE *msg, int len );
// 查询传感器电源状态
char Gm_GetSensorsPowerState(int port);
@ -465,15 +417,15 @@ int FindNextShxyProtocolCommand( int devidx );
// 倾角命令校验码计算
unsigned char CalLpc(unsigned char *msg, int len);
// 读上海欣影传感器协议数据
void ShxyProtocolRecvData(int commid, uint8_t *buf, int len);
void ShxyProtocolRecvData(int commid, u_char *buf, int len);
// 检查检验和是否正确
int CheckShxyProtocolLpcError( uint8_t* msg, int len );
int CheckShxyProtocolLpcError( u_char* msg, int len );
// 把16进制和10进制ASCII字符串转换成int整数
int ATOI(char *buf);
//生成倾角命令
void MakeShxyProtocolPollCommand(int portno, uint8_t cmdidx);
void MakeShxyProtocolPollCommand(int portno, BYTE cmdidx);
// 上海欣影传感器协议数据处理
void ShxyProtocolDataProcess( int commid);
// 控制关闭传感器电源
@ -483,7 +435,8 @@ void ShxyProtocolDataProcess( int commid);
int SaveImageDataTofile(int devno);
void Collect_sensor_data();
int CameraPhotoCmd(int phototime, unsigned char channel, int cmdidx, unsigned char bImageSize, unsigned char presetno, const char *serfile, unsigned int baud, int addr);
void CameraPhotoCmd(int phototime, u_char channel, int cmdidx, u_char bImageSize, u_char presetno);
/* 数据和图片采集数据返回函数 开始*/
int GetWeatherData(Data_DEF *data, int datano);
@ -510,48 +463,5 @@ int GetImage(int devno, IMAGE_DEF *photo);
/* 数据和图片采集数据返回函数 结束*/
// 生成一个随机整数
int GeneratingRandomNumber();
int Gm_SetSerialPortParam(int commid);
void ClearCameraCmdAllFlag(SIO_PARAM_SERIAL_DEF *pPortParam);
void ClearCameraCmdFormPollCmdBuf(SIO_PARAM_SERIAL_DEF *pPortParam);
int Gm_OpenCameraSerial(SIO_PARAM_SERIAL_DEF *pPortParam, const char *serfile, unsigned int baud);
int Gm_SetCameraSerialPortParam(int fd, unsigned int baud);
int GM_CameraComSend(unsigned char * cSendBuf, size_t nSendLen, int fd);
void SendCameraCmdFormPollCmdBuf(SIO_PARAM_SERIAL_DEF *pPortParam);
void Gm_FindCameraCommand(SIO_PARAM_SERIAL_DEF *pPortParam);
void GM_CameraSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam);
int GM_IsCloseCamera(SIO_PARAM_SERIAL_DEF *pPortParam);
int GM_CameraSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam);
int QueryPtzState(PTZ_STATE *ptz_state, int cmdidx, const char *serfile, unsigned int baud, int addr);
void MakePtzStateQueryCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint8_t cmdidx);
int Query_BDGNSS_Data(BD_GNSS_DATA *BD_data, int samptime, const char *serfile, unsigned int baud);
int GM_BdSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam);
void GM_BdSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam);
void BdRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len);
unsigned char BDXorCheck(unsigned char *msg, int len);
void BD_NMEA0183_PortDataProcess(SIO_PARAM_SERIAL_DEF *curserial);
char** BD_NMEA0183_SplitString(char *str, int *total_fields);
int BD_get_BDRMC_data(SIO_PARAM_SERIAL_DEF *curserial);
#endif // __SENSOR_PROTOCOL_H__
#endif //WEATHERCOMM_H

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save