#include <jni.h>
#include <string>

#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <linux/spi/spidev.h>
#include <android/log.h>
#include <stdio.h>
//#include <io.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <termios.h>
#include <asm/termbits.h>
#include <time.h>
#include "GPIOControl.h"
#include "SerialComm.h"
#include <sys/time.h>

#include <AndroidHelper.h>
#include <Client/SensorsProtocol.h>
//#include "Eint.h"

#include <algorithm>

SIO_PARAM_SERIAL_DEF serialport[MAX_SERIAL_PORT_NUM];
SERIAL_PARAM devparam[MAX_SERIAL_DEV_NUM];
SRDT_DEF	srdt;
AI_DEF		weatherpntmsg[WEATHER_DATA_NUM];
AI_DEF		rallypntmsg[6][RALLY_DATA_NUM];
AI_DEF		slantpntmsg[6][SLANTANGLE_DATA_NUM];

static void setInt(int cmd, int value)
{
	int fd = open("/dev/mtkgpioctrl", O_RDONLY);
	IOT_PARAM param;
	param.cmd = cmd;
	param.value = value;
	// LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
	if (fd > 0)
	{
		ioctl(fd, IOT_PARAM_WRITE, &param);
		// LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
		close(fd);
	}
	//return;
}

int getInt(int cmd)
{
	int fd = open("/dev/mtkgpioctrl", O_RDONLY);
	// LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
	if (fd > 0)
	{
		IOT_PARAM param;
		param.cmd = cmd;
		ioctl(fd, IOT_PARAM_READ, &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;
}

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)
{
#ifdef ENABLE_3V3_ALWAYS
	setInt(CMD_SET_CAM_3V3_EN_STATE, 1);
#else
	setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
#endif
}

#if 0
/*********************************************************************************
*						            气象数据处理							         *
**********************************************************************************/
static void PortDataProcess(void)
{
	float			fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
	//uint16_t		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;
		}
	}
}

/***************************************************************
*    		     		按照协议格式化接收数据				       *
***************************************************************/
static void RecvData(u_char *buf, int len)// 规约读数据处理
{
	int  				i, ictime;
	//uint16_t				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 int64_t get_msec(void)
{
	struct timeval tv;

	gettimeofday(&tv, NULL);
	int64_t 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;
	int64_t ictime, iruntime, isendtime, irecvtime;
	unsigned char sendbuf[] = { 0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16 };
	char recvbuf[256], szbuf[512];
	//char serial_description[] = "/dev/ttyS0";

#if 0
	DIR *dir = opendir("/dev");
	if (dir == NULL) {
		LOGE("_test_ opendir");
		return -1;
	}

	// 读取目录项
	struct dirent *entry;
	while ((entry = readdir(dir)) != NULL) {
		// 过滤出串口设备，通常以"ttyS"或"ttyUSB"开头
		if ((strncmp(entry->d_name, "ttyS2", 5) == 0) ||
			(strncmp(entry->d_name, "ttyS0", 5) == 0)) {
			LOGE("_test_ Found serial port: %s\n", entry->d_name);
		}
	}

	// 关闭目录
	closedir(dir);
#endif
	serialport.RevCmdFlag = 1;
	serialport.m_iRecvLen = 0;
	serialport.m_iRevStatus = 0;

	set12VEnable(true);
	setCam3V3Enable(true);
	setRS485Enable(true);
	sleep(2);
	//ictime = (int)time(NULL);
	ictime = get_msec();
	for (;;)
	{
		if (fd < 0)
		{
			fd = open(weatherport.pathname, O_RDWR | O_NDELAY);
			//fd = open(weatherport.pathname, O_RDWR | O_NOCTTY);
			if (fd < 0)
			{
				LOGE("_test_ open serial error \n");
				perror(weatherport.pathname);
				return -1;
			}

			ret = set_port_attr(fd, weatherport.baudrate, weatherport.databit, weatherport.stopbit, weatherport.parity, 0, 0);/*9600 8n1 */
			if (ret < 0)
			{
				LOGE("_test_ set uart arrt faile \n");
				return -1;
			}
		}

		usleep(10000);
		//iruntime = (int)time(NULL);
		iruntime = get_msec();
		if ((iruntime - ictime > 120000) || (iruntime - ictime < 0))
			ictime = iruntime;
		if (iruntime - ictime > 20000)
		{
			memset(szbuf, 0, sizeof(szbuf));
			sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime - ictime) / 1000.0);
			LOGE("%s", szbuf);
			break;
		}

		if (1 == serialport.RevCmdFlag)
		{
			set485WriteMode();

			len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */
			serialport.RevCmdFlag = 0;
			LOGE("发送命令时间差%ld毫秒", get_msec() - isendtime);
			//isendtime = time(NULL);
			isendtime = get_msec();
			if (len < 0) {
				LOGE("write data error \n");
				return -1;
			}
			else {
				memset(szbuf, 0, sizeof(szbuf));
				sprintf(szbuf, "Send：");
				for (i = 0; i < len; i++) {
					sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]);
				}
				LOGE("%s", szbuf);
				//icnt = 0;
				//inum++;
			}
			tcdrain(fd);
			//usleep(50000);
		}
		else
		{
			//irecvtime = time(NULL);
			irecvtime = get_msec();
			if ((irecvtime - isendtime > 6000) || (irecvtime - isendtime < 0))
				isendtime = irecvtime;
			if (irecvtime - isendtime > 300)
			{
				LOGE("传感器超过%ld毫秒未应答", irecvtime - isendtime);
				serialport.RevCmdFlag = 1;
				serialport.m_iRecvLen = 0;
				serialport.m_iRevStatus = 0;
				close(fd);
				fd = -1;
				continue;
			}
		}
		set485ReadMode();
		memset(recvbuf, 0, sizeof(recvbuf));
		len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */
		if (len < 0) {
			LOGE("serial read error \n");
			continue;
		}
		if (0 == len)
		{
			//icnt++;
			continue;
		}
		memset(szbuf, 0, sizeof(szbuf));
		sprintf(szbuf, "Recv：");
		for (i = 0; i < len; i++) {
			sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]);
		}
		__android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf);
		RecvData((u_char*)recvbuf, len);
		//LOGE("一周期空循环次数%d, 读取次数%d, 时间：%d %d", icnt, inum, (int)time(NULL), itimecnt);
		icnt = 0;
		//serialport.RevCmdFlag =1;
	}

	close(fd);
	set12VEnable(false);
	setCam3V3Enable(false);
	setRS485Enable(false);

	//exit(-1);
	return(0);
}

int serial_port_comm()
{
	SERIAL_PARAM  portparm;

	//struct timeval tv;

	//gettimeofday(&tv, NULL);
	//int64_t time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec;

	//LOGE("Current time in microseconds: %ld\n", time_in_microseconds);

#if 1
	memset(portparm.pathname, 0, sizeof(portparm.pathname));
	sprintf(portparm.pathname, "/dev/ttyS0");
	portparm.parity = 'N';
	portparm.databit = 8;
	portparm.baudrate = B9600;
	memset(portparm.stopbit, 0, sizeof(portparm.stopbit));
	sprintf(portparm.stopbit, "1");
#endif
	//itimecnt = (int)time(NULL);

	//for(;;)
	weather_comm(portparm);
	return 0;
}
#endif

static speed_t getBaudrate(unsigned int baudrate)
{
	switch (baudrate) {
	case 0: return B0;
	case 50: return B50;
	case 75: return B75;
	case 110: return B110;
	case 134: return B134;
	case 150: return B150;
	case 200: return B200;
	case 300: return B300;
	case 600: return B600;
	case 1200: return B1200;
	case 1800: return B1800;
	case 2400: return B2400;
	case 4800: return B4800;
	case 9600: return B9600;
	case 19200: return B19200;
	case 38400: return B38400;
	case 57600: return B57600;
	case 115200: return B115200;
	case 230400: return B230400;
	case 460800: return B460800;
	case 500000: return B500000;
	case 576000: return B576000;
	case 921600: return B921600;
	case 1000000: return B1000000;
	case 1152000: return B1152000;
	case 1500000: return B1500000;
	case 2000000: return B2000000;
	case 2500000: return B2500000;
	case 3000000: return B3000000;
	case 3500000: return B3500000;
	case 4000000: return B4000000;
	default: return B9600;
	}
}

static int64_t get_msec()
{
	struct timeval tv;
	int64_t time_in_msec = 0;

	gettimeofday(&tv, NULL);
	time_in_msec = tv.tv_sec;
	time_in_msec *= 1000;
	time_in_msec += tv.tv_usec / 1000;

	return time_in_msec;
}

/*
打开串口电源
*/
void Gm_OpenSerialPower()
{
	/*由传送的主站的地方来控制串口电源，这里不实现*/;
}

// 关闭串口电源
void Gm_CloseSerialPower()
{
}

// 关闭传感器电源
void Gm_CloseSensorsPower()
{
	//char		iIoNo;
	//char		szbuf[128];
	int         igpio;

	//sprintf(szbuf, "Close Sensors port %d Power!", port);

	/* 关闭电源*/
	//switch(port)
	/* 根据硬件具体布置最后调整，目前是微拍板子的来控制*/
/*    set12VEnable(false);
	setCam3V3Enable(false);
	setRS485Enable(false);

#if 0
	setInt(CMD_SET_WTH_POWER, 0);
	setInt(CMD_SET_PULL_POWER, 0);
	setInt(CMD_SET_ANGLE_POWER, 0);
	setInt(CMD_SET_OTHER_POWER, 0);
	setInt(CMD_SET_PIC1_POWER, 0);

	sleep(3);
	igpio = getInt(CMD_SET_WTH_POWER);
	igpio = getInt(CMD_SET_PULL_POWER);
	igpio = getInt(CMD_SET_ANGLE_POWER);
	igpio = getInt(CMD_SET_OTHER_POWER);
	igpio = getInt(CMD_SET_PIC1_POWER);
#endif
#if 1
	setInt(CMD_SET_SPI_POWER, 1);
	setInt(CMD_SET_485_en0, 1);
	setInt(CMD_SET_485_en1, 1);
	setInt(CMD_SET_485_en2, 1);
	setInt(CMD_SET_485_en3, 1);
	setInt(CMD_SET_485_en4, 1);
#else
	setInt(CMD_SET_SPI_POWER, 0);
	setInt(CMD_SET_485_en0, 0);
	setInt(CMD_SET_485_en1, 0);
	setInt(CMD_SET_485_en2, 0);
	setInt(CMD_SET_485_en3, 0);
	setInt(CMD_SET_485_en4, 0);
	sleep(3);
	igpio = getInt(CMD_SET_SPI_POWER);
	igpio = getInt(CMD_SET_485_en0);
	igpio = getInt(CMD_SET_485_en1);
	igpio = getInt(CMD_SET_485_en2);
	igpio = getInt(CMD_SET_485_en3);
	igpio = getInt(CMD_SET_485_en4);
#endif
*/
}

// 打开传感器电源
void Gm_OpenSensorsPower()
{
	//char		iIoNo;
/*    int     igpio;
	char		szbuf[128];

	//if(0 == port)
	  //  return;
	//sprintf(szbuf, "Open Sensors port %d Power!", port);

	//set12VEnable(true);
	setCam3V3Enable(true);
	setRS485Enable(true);

#if 0
	setInt(CMD_SET_WTH_POWER, 0);
	setInt(CMD_SET_PULL_POWER, 0);
	setInt(CMD_SET_ANGLE_POWER, 0);
	setInt(CMD_SET_OTHER_POWER, 0);
	setInt(CMD_SET_PIC1_POWER, 0);
#else
	setInt(CMD_SET_WTH_POWER, 1);
	setInt(CMD_SET_PULL_POWER, 1);
	setInt(CMD_SET_ANGLE_POWER, 1);
	setInt(CMD_SET_OTHER_POWER, 1);
	setInt(CMD_SET_PIC1_POWER, 1);
	//sleep(3);
	igpio = getInt(CMD_SET_WTH_POWER);
	igpio = getInt(CMD_SET_PULL_POWER);
	igpio = getInt(CMD_SET_ANGLE_POWER);
	igpio = getInt(CMD_SET_OTHER_POWER);
	igpio = getInt(CMD_SET_PIC1_POWER);

#endif
#if 1
	setInt(CMD_SET_SPI_POWER, 1);
	setInt(CMD_SET_485_en0, 1);
	setInt(CMD_SET_485_en1, 1);
	setInt(CMD_SET_485_en2, 1);
	setInt(CMD_SET_485_en3, 1);
	setInt(CMD_SET_485_en4, 1);

	//sleep(3);
	igpio = getInt(CMD_SET_SPI_POWER);
	igpio = getInt(CMD_SET_485_en0);
	igpio = getInt(CMD_SET_485_en1);
	igpio = getInt(CMD_SET_485_en2);
	igpio = getInt(CMD_SET_485_en3);
	igpio = getInt(CMD_SET_485_en4);

#else
	setInt(CMD_SET_485_en0, 0);
	setInt(CMD_SET_485_en1, 0);
	setInt(CMD_SET_485_en2, 0);
	setInt(CMD_SET_485_en3, 0);
	setInt(CMD_SET_485_en4, 0);
#endif

	// 打开电源
	//switch(port)
*/
}

// 查询传感器电源状态
char Gm_GetSensorsPowerState(int port)
{
	char		iIoNo, cstate = 0;
	//char		szbuf[128];

	/* 查询电源状态*/
	//switch(port)


	return	cstate;
}

void BytestreamLOG(int commid, char* describe, u_char* buf, int len, char flag)
{
	int     i;
	char    szbuf[4096];

	memset(szbuf, 0, sizeof(szbuf));
	if (NULL != describe)
		strncpy(szbuf, describe, strlen(describe));
	for (i = 0; i < len; i++)
	{
		sprintf(szbuf, "%s %02X", szbuf, buf[i]);
	}
	SaveLogTofile(commid, szbuf);
	switch (flag)
	{
	case 'E':
		ALOGE("%s", szbuf);
		break;
	case 'I':
		ALOGI("%s", szbuf);
		break;
	case 'D':
		ALOGD("%s", szbuf);
		break;
	case 'V':
		ALOGI("%s", szbuf);
		break;
	case 'W':
		ALOGW("%s", szbuf);
		break;
	default:
		ALOGI("%s", szbuf);
		break;
	}
}

// 打开串口通讯
void Gm_OpenSerialPort(int devidx)
{
	int	fd = -1;
	char szbuf[512];

	if ((devidx < 0) || (devidx >= MAX_SERIAL_DEV_NUM))
		return;
	memset(szbuf, 0, sizeof(szbuf));
	if (serialport[devparam[devidx].commid].fd <= 0)
	{
		fd = open(devparam[devidx].pathname, O_RDWR | O_NDELAY);
		if (fd < 0)
		{
			sprintf(szbuf, "装置%d 打开串口%d失败！fd=%d", devidx + 1, devparam[devidx].commid + 1, fd);
			DebugLog(devparam[devidx].commid, szbuf, 'E');
			return;
		}
		sprintf(szbuf, "装置%d 打开串口%d %s成功！fd=%d", devidx + 1, devparam[devidx].commid + 1, devparam[devidx].pathname, fd);
		DebugLog(devparam[devidx].commid, szbuf, 'I');
		serialport[devparam[devidx].commid].fd = fd;
		return;
	}
	sprintf(szbuf, "装置%d 串口%d %s已经打开！fd=%d", devidx + 1, devparam[devidx].commid + 1, devparam[devidx].pathname, serialport[devparam[devidx].commid].fd);
	DebugLog(devparam[devidx].commid, szbuf, 'I');
}

// 关闭串口通讯
void Gm_CloseSerialPort()
{
	int     i;

	for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
	{
		if (serialport[i].fd > 0)
		{
			close(serialport[i].fd);
			serialport[i].fd = -1;
		}
	}

}

/*******************************************************************************
函数名称: int GM_SerialComSend(const uint8_t * cSendBuf, uint32_t nSendLen, int commid)
功能说明:串口发送数据 返回实际发送的字节数
输入参数:
输出参数:
其它说明:
*********************************************************************************/
int GM_SerialComSend(unsigned char * cSendBuf, size_t nSendLen, int commid)
{
	int     i, len;
	char    szbuf[512];

	memset(szbuf, 0, sizeof(szbuf));
	len = write(serialport[commid].fd, cSendBuf, (size_t)nSendLen);/* 向串囗发送字符串 */
	//serialport[commid].RevCmdFlag = 0;
	//LOGE("发送命令时间差%ld毫秒", get_msec() - isendtime);
	//isendtime = time(NULL);
	//isendtime = get_msec();
	if (len < 0)
	{
		sprintf(szbuf, "write data error ");
		DebugLog(commid, szbuf, 'E');
		return -1;
	}
	else if (len > 0)
	{
		;
	}
	return len;
}

int Gm_SetSerialPortParam(int commid)
{
	int ret;
	char szbuf[128];
	SERIAL_PARAM *pPortParam = NULL;

	pPortParam = &devparam[srdt.curdevidx[commid]];
	ret = set_port_attr(serialport[commid].fd, pPortParam->baudrate, pPortParam->databit, pPortParam->stopbit, pPortParam->parity, 0, 0);/*9600 8n1 */
	if (ret < 0)
	{
		memset(szbuf, 0, sizeof(szbuf));
		sprintf(szbuf, "串口%d 波特率等参数设置错误！", commid + 1);
		DebugLog(commid, szbuf, 'E');
		return -1;
	}
	return ret;
}

void Gm_InitSerialComm_Test()
{
	int	i, j;
	SENSOR_PARAM sensorParam[MAX_SERIAL_DEV_NUM];

#if 0
	srdt.PtzCmdType = Cmd_Cancel;			// 云台指令类型
	for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
	{
		//***************** 串行端口信息 ************************
		//g_serialparam[i].Baud = 1200;
		//g_serialparam[i].dataBits = 8;
		//g_serialparam[i].stopBits = 1;
		//g_serialparam[i].parity = 0;
		//******************** Poll Cmd ****************************
		serialport[i].Retry = 0;
		//serialport[i].RetryTime = 500/TIMER_CNT;
		j = TIMER_CNT;
		serialport[i].RetryTime = 300 / TIMER_CNT;
		j = 1500 / TIMER_CNT;
		serialport[i].WaitTime = 0;
		memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH);	// 接收数据缓存区
		ClearCmdFormPollCmdBuf(i);
	}
	//g_serialparam[1].Baud = 1200;
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
		devparam[i].IsNoInsta = 0;
#endif
	//if(NULL == sensorParam)
	//    return;
	memset(sensorParam, 0, sizeof(sensorParam));
	//#if COLLECT_DATA
	sensorParam[0].SensorsType = WEATHER_PROTOCOL;
	sensorParam[0].baudrate = 9600;
	sensorParam[0].databit = 8;
	//memset(devparam[0].stopbit, 0, sizeof(devparam[0].stopbit));
	//sprintf(devparam[0].stopbit, "1");
	sensorParam[0].stopbit = 1;
	sensorParam[0].parity = 'n';
	sensorParam[0].IsNoInsta = 1;
	sensorParam[0].devaddr = 4;
	memset(sensorParam[0].pathname, 0, sizeof(sensorParam[0].pathname));
	sprintf(sensorParam[0].pathname, "/dev/ttysWK3");

	sensorParam[1].SensorsType = WEATHER_PROTOCOL;
	sensorParam[1].baudrate = 9600;
	sensorParam[1].databit = 8;
	//memset(devparam[1].stopbit, 0, sizeof(devparam[1].stopbit));
	//sprintf(devparam[1].stopbit, "1");
	sensorParam[1].stopbit = 1;
	sensorParam[1].parity = 0;
	sensorParam[1].IsNoInsta = 1;
	sensorParam[1].devaddr = 1;
	memset(sensorParam[1].pathname, 0, sizeof(sensorParam[1].pathname));
	sprintf(sensorParam[1].pathname, "/dev/ttysWK3");

	sensorParam[2].SensorsType = RALLY_PROTOCOL;
	sensorParam[2].baudrate = 9600;
	sensorParam[2].databit = 8;
	//memset(devparam[2].stopbit, 0, sizeof(devparam[2].stopbit));
	//sprintf(devparam[2].stopbit, "1");
	sensorParam[2].stopbit = 1;
	sensorParam[2].parity = 0;
	sensorParam[2].IsNoInsta = 1;
	//sensorParam[2].PowerPort = 3;
	//sensorParam[2].devaddr = 13;
	sensorParam[2].devaddr = 13;
	memset(sensorParam[2].pathname, 0, sizeof(sensorParam[2].pathname));
	sprintf(sensorParam[2].pathname, "/dev/ttysWK1");

	sensorParam[5].SensorsType = RALLY_PROTOCOL;
	sensorParam[5].baudrate = 9600;
	sensorParam[5].databit = 8;
	//memset(devparam[2].stopbit, 0, sizeof(devparam[2].stopbit));
	//sprintf(devparam[2].stopbit, "1");
	sensorParam[5].stopbit = 1;
	sensorParam[5].parity = 0;
	sensorParam[5].IsNoInsta = 1;
	sensorParam[5].devaddr = 10;
	memset(sensorParam[5].pathname, 0, sizeof(sensorParam[3].pathname));
	sprintf(sensorParam[5].pathname, "/dev/ttysWK1");

	sensorParam[4].SensorsType = RALLY_PROTOCOL;
	sensorParam[4].baudrate = 9600;
	sensorParam[4].databit = 8;
	//memset(devparam[2].stopbit, 0, sizeof(devparam[2].stopbit));
	//sprintf(devparam[2].stopbit, "1");
	sensorParam[4].stopbit = 1;
	sensorParam[4].parity = 0;
	sensorParam[4].IsNoInsta = 1;
	//sensorParam[2].PowerPort = 3;
	//sensorParam[2].devaddr = 13;
	sensorParam[4].devaddr = 12;
	memset(sensorParam[4].pathname, 0, sizeof(sensorParam[4].pathname));
	sprintf(sensorParam[4].pathname, "/dev/ttysWK1");

	sensorParam[6].SensorsType = SLANT_PROTOCOL;
	sensorParam[6].baudrate = 9600;
	sensorParam[6].databit = 8;
	//memset(devparam[13].stopbit, 0, sizeof(devparam[13].stopbit));
	//sprintf(devparam[13].stopbit, "1");
	sensorParam[6].stopbit = 1;
	sensorParam[6].parity = 0;
	//devparam[13].PowerPort = 4;
	sensorParam[6].IsNoInsta = 1;
	sensorParam[6].devaddr = 2;
	memset(sensorParam[6].pathname, 0, sizeof(sensorParam[6].pathname));
	sprintf(sensorParam[6].pathname, "/dev/ttysWK0");


	sensorParam[7].SensorsType = SLANT_PROTOCOL;
	sensorParam[7].baudrate = 9600;
	sensorParam[7].databit = 8;
	//memset(devparam[13].stopbit, 0, sizeof(devparam[13].stopbit));
	//sprintf(devparam[13].stopbit, "1");
	sensorParam[7].stopbit = 1;
	sensorParam[7].parity = 0;
	//devparam[13].PowerPort = 4;
	sensorParam[7].IsNoInsta = 1;
	sensorParam[7].devaddr = 3;
	memset(sensorParam[7].pathname, 0, sizeof(sensorParam[7].pathname));
	sprintf(sensorParam[7].pathname, "/dev/ttysWK0");

	sensorParam[13].SensorsType = SLANT_PROTOCOL;
	sensorParam[13].baudrate = 9600;
	sensorParam[13].databit = 8;
	//memset(devparam[13].stopbit, 0, sizeof(devparam[13].stopbit));
	//sprintf(devparam[13].stopbit, "1");
	sensorParam[13].stopbit = 1;
	sensorParam[13].parity = 0;
	//devparam[13].PowerPort = 4;
	sensorParam[13].IsNoInsta = 1;
	sensorParam[13].devaddr = 5;
	memset(sensorParam[13].pathname, 0, sizeof(sensorParam[13].pathname));
	sprintf(sensorParam[13].pathname, "/dev/ttysWK0");
#if 0
	devparam[14].ProtocolIdx = SLANT_PROTOCOL;
	devparam[14].baudrate = 1200;
	devparam[14].databit = 8;
	devparam[14].stopbit = 1;
	devparam[14].parity = 0;
	devparam[14].IsNoInsta = 1;
	//devparam[14].PowerPort = 2;
	devparam[14].devaddr = 3;

	devparam[15].ProtocolIdx = LEIRALLY_PROTOCOL;
	//#endif
	devparam[15].ProtocolIdx = WIND_PROTOCOL;
	devparam[15].baudrate = 9600;
	devparam[15].databit = 8;
	devparam[15].stopbit = 1;
	devparam[15].parity = 0;
	devparam[15].IsNoInsta = 1;
	devparam[15].PowerPort = 14;
	devparam[15].devaddr = 1;

#endif
	//#else
	sensorParam[3].SensorsType = PELCO_D_PROTOCOL;
	sensorParam[3].baudrate = 38400;
	sensorParam[3].databit = 8;
	sensorParam[3].stopbit = 1;
	sensorParam[3].parity = 0;
	sensorParam[3].IsNoInsta = 1;
	//devparam[3].PowerPort = 15;
	sensorParam[3].CameraChannel = 1;
	sensorParam[3].devaddr = 0;
	memset(sensorParam[3].pathname, 0, sizeof(sensorParam[3].pathname));
	sprintf(sensorParam[3].pathname, "/dev/ttyS1");
	//#endif
	Gm_InitSerialComm(sensorParam, "/sdcard/photo/");
}

// 初始化所有串口及所接传感器的配置
void Gm_InitSerialComm(SENSOR_PARAM *sensorParam, char *filedir)
{
	int	i;
	char	szbuf[128];

	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		memset(&devparam[i], 0, sizeof(SERIAL_PARAM));
		memset(&srdt, 0, sizeof(srdt));
		srdt.camerauseserial = -1;
	}
	for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
	{
		memset(&serialport[i], 0, sizeof(SIO_PARAM_SERIAL_DEF));
		serialport[i].fd = -1;
		serialport[i].lsendtime = get_msec();
	}
	if (NULL == sensorParam)
		return;
	//memset(sensorParam, 0, sizeof(sensorParam));
	//Gm_InitSerialComm_Test(sensorParam);
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		devparam[i].IsNoInsta = sensorParam[i].IsNoInsta;
		if (0 == sensorParam[i].IsNoInsta)
			continue;
		devparam[i].ProtocolIdx = sensorParam[i].SensorsType;
		devparam[i].devaddr = sensorParam[i].devaddr;
		devparam[i].baudrate = getBaudrate(sensorParam[i].baudrate);
		memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
		memmove(devparam[i].pathname, sensorParam[i].pathname, sizeof(devparam[i].pathname));
		devparam[i].databit = sensorParam[i].databit;
		devparam[i].stopbit = (int)(sensorParam[i].stopbit * 10);
		devparam[i].CameraChannel = sensorParam[i].CameraChannel;
		devparam[i].Phase = sensorParam[i].Phase;
	}

#if 1
	//******************** 端口基本信息 ************************
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		memset(szbuf, 0, sizeof(szbuf));
		switch (sensorParam[i].SensorsType)
		{
		case 0:
			sprintf(szbuf, "传感器%d没有接!", i + 1);
			break;
		case WEATHER_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是气象传感器!", i + 1);
			break;
		case SERIALCAMERA_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是串口摄像机!", i + 1);
			break;
		case PELCO_P_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是PELCO_P摄像机!", i + 1);
			break;
		case SLANT_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是倾角!", i + 1);
			break;
		case WIND_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是风速风向传感器", i + 1);
			break;
		case RALLY_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是拉力!", i + 1);
			break;
		case PELCO_D_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是PELCO_D摄像机!", i + 1);
			break;
		case RESERVE5_PROTOCOL:
			sprintf(szbuf, "传感器%d接的是加密芯片", i + 1);
			break;
		default:
			sprintf(szbuf, "传感器%d没有接!", i + 1);
			break;
		}

		sprintf(szbuf, "%s 地址%d!；", szbuf, sensorParam[i].devaddr);
		if (0 == sensorParam[i].IsNoInsta)
			sprintf(szbuf, "没有启用!；");
		else
		{
			sprintf(szbuf, "%s 已启用!；", szbuf);
			DebugLog(8, szbuf, 'I');
		}
	}
	if (NULL == filedir)
		return;
	memset(srdt.filedir, 0, sizeof(srdt.filedir));
	memmove(srdt.filedir, filedir, std::min(sizeof(srdt.filedir), strlen(filedir)));
	FindDevUseSerialCommNo();

#if 0
	//Collect_sensor_data();
	//#else
	for (;;)
	{
		CameraPhotoCmd(sensorParam, 1, 0, 6, 1);
		sleep(5);

		//CameraPhotoCmd(sensorParam, 1, 10017, 0, 1);
		//sleep(5);

		//CameraPhotoCmd(sensorParam, 1, MOVE_LEFT, 0, 0);
		//sleep(5);
		//CameraPhotoCmd(sensorParam, 1, MOVE_DOWN, 0, 0);
		//sleep(5);
		//CameraPhotoCmd(sensorParam, 1, MOVE_RIGHT, 0, 0);
		//sleep(5);
		//CameraPhotoCmd(sensorParam, 1, MOVE_UP, 0, 0);
		//sleep(5);
		//CameraPhotoCmd(sensorParam, 1, 10017, 0, 2);
		//sleep(5);
		//CameraPhotoCmd(sensorParam, 1, ZOOM_TELE, 0, 0);
		//sleep(5);
		//CameraPhotoCmd(sensorParam, 1, ZOOM_WIDE, 0, 0);
		//sleep(5);
	}
#endif
#endif
}

void testComm()
{
	int	i;
	char	szbuf[128];
	//SENSOR_PARAM sensorParam[MAX_SERIAL_DEV_NUM];

	//memset(sensorParam, 0, sizeof(sensorParam));
	Gm_InitSerialComm_Test();
	for (;;)
	{
#if COLLECT_DATA

		Collect_sensor_data();
#else
		sleep(15);
		CameraPhotoCmd(time(NULL), 1, 0, 6, 1);
		sleep(5);

		CameraPhotoCmd(time(NULL), 1, 10017, 0, 2);
		sleep(5);

		CameraPhotoCmd(0, 1, MOVE_LEFT, 0, 0);
		sleep(5);
		CameraPhotoCmd(0, 1, MOVE_DOWN, 0, 0);
		sleep(5);
		CameraPhotoCmd(0, 1, MOVE_RIGHT, 0, 0);
		sleep(5);
		CameraPhotoCmd(0, 1, MOVE_UP, 0, 0);
		sleep(5);
		CameraPhotoCmd(0, 1, 10017, 0, 1);
		sleep(5);
		CameraPhotoCmd(0, 1, ZOOM_TELE, 0, 0);
		sleep(5);
		CameraPhotoCmd(0, 1, ZOOM_WIDE, 0, 0);
		sleep(5);
		CameraPhotoCmd(time(NULL), 1, 0, 6, 2);
		sleep(5);

#endif
	}
#if 1
	//******************** 端口基本信息 ************************
	/*for(i=0; i<MAX_SERIAL_DEV_NUM; i++)
	{
		memset(szbuf, 0, sizeof(szbuf));
		switch (sensorParam[i].SensorsType)
		{
			case 0:
				sprintf(szbuf, "传感器%d没有接!", i + 1);
				break;
			case WEATHER_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是气象传感器!", i + 1);
				break;
			case SERIALCAMERA_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是串口摄像机!", i + 1);
				break;
			case PELCO_P_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是PELCO_P摄像机!", i + 1);
				break;
			case SLANT_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是倾角!", i + 1);
				break;
			case WIND_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是风速风向传感器", i + 1);
				break;
			case RALLY_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是拉力!", i + 1);
				break;
			case PELCO_D_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是PELCO_D摄像机!", i + 1);
				break;
			case RESERVE5_PROTOCOL:
				sprintf(szbuf, "传感器%d接的是加密芯片", i + 1);
				break;
			default:
				sprintf(szbuf, "传感器%d没有接!", i + 1);
				break;
		}
		//LOGI("%s", szbuf);

		sprintf(szbuf, "%s 地址%d!；", szbuf, sensorParam[i].devaddr);
		//LOGI("%s", szbuf);
		if (0 == sensorParam[i].IsNoInsta)
			sprintf(szbuf, "没有启用!；");
		else
		{
			sprintf(szbuf, "%s 已启用!；", szbuf);
			LOGI("%s", szbuf);
		}
	}*/
	//for(;;)
	{
		//CameraPhotoCmd(time(NULL), 1, 0, 6, 1);
		//sleep(5);
	}

#endif
}

// 通过传感器名称来确定使用的串口号
void FindDevUseSerialCommNo()
{
	int	i;

	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		if (0 == devparam[i].IsNoInsta)
			continue;
		switch (devparam[i].ProtocolIdx)
		{
		case	WEATHER_PROTOCOL:
		case	WIND_PROTOCOL:
			//memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
			/* 目前还不确定具体串口分配，暂时默认使用串口1</dev/ttyS0>*/
			//sprintf(devparam[i].pathname, "/dev/swk3");
			devparam[i].commid = 3;
			break;
		case	SLANT_PROTOCOL:
			//memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
			/* 目前还不确定具体串口分配，暂时默认使用串口1</dev/ttyS0>*/
			//sprintf(devparam[i].pathname, "/dev/swk2");
			devparam[i].commid = 2;
			break;
		case	RALLY_PROTOCOL:
			//memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
			/* 目前还不确定具体串口分配，暂时默认使用串口1</dev/ttyS0>*/
			//sprintf(devparam[i].pathname, "/dev/swk1");
			devparam[i].commid = 1;
			break;
		case	PELCO_D_PROTOCOL:		/* 摄像机协议*/
		case	PELCO_P_PROTOCOL:		/* 摄像机协议*/
		case	SERIALCAMERA_PROTOCOL:	/* 串口摄像机协议*/
			//memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
			/* 目前还不确定//具体串口分配，暂时默认使用串口1</dev/ttyS0>*/
			//sprintf(devparam[i].pathname, "/dev/ttyS1");
			devparam[i].commid = 0;
			srdt.camerauseserial = 0;
			break;
		default:
			devparam[i].IsNoInsta = 0;
			break;
		}
	}
}

void GM_StartSerialComm()
{
	int 	i, j, commid;
	char	szbuf[64], logbuf[128];
	//int64_t    polltime=0;

	// 此处不能对轮询设备标识清零，否则如果先起摄像机，就会导致poll乱掉
	//memset((void*)srdt.curdevidx, 0, sizeof(srdt.curdevidx));
	//Gm_OpenSerialPower(); /* 不在这使用*/
	//FindDevUseSerialCommNo();
	// 初始化串口使用状态(需要考虑不同时间启用了摄像机使用)
	for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
	{
		if (i == srdt.camerauseserial)
			continue;
		serialport[i].Retry = 0;
		serialport[i].RetryTime = 800;
		serialport[i].WaitTime = 20;
		serialport[i].m_iRevStatus = 0;
		serialport[i].m_iRecvLen = 0;
		serialport[i].m_iNeedRevLength = 0;
		serialport[i].fd = -1;
		memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH);	// 接收数据缓存区
		ClearCmdFormPollCmdBuf(i);
	}
#if 0/* 简化插入使用摄像机过程，摄像机使用单独的串口*/
	else
	{
	for (i = 0; i < MAX_SERIAL_PORT_NUM; i++)
	{
		for (j = 0; j < MAX_SERIAL_DEV_NUM; j++)
		{
			if (((PELCO_D_PROTOCOL == devparam[i].ProtocolIdx) || (PELCO_P_PROTOCOL == devparam[i].ProtocolIdx)\
				|| (SERIALCAMERA_PROTOCOL == devparam[i].ProtocolIdx)) && (1 == devparam[i].IsNoInsta))
				break;
		}
		if (j < MAX_SERIAL_DEV_NUM)
			continue;
		serialport[i].m_iRevStatus = 0;
		serialport[i].m_iRecvLen = 0;
		serialport[i].m_iNeedRevLength = 0;
		serialport[i].fd = -1;
		ClearCmdAllFlag(i);
	}
	}
#endif
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		if (0 == devparam[i].IsNoInsta)
		{
			srdt.ms_dev[i].IsNeedSerial = 0;
			continue;
		}
		memset(szbuf, 0, sizeof(szbuf));
		switch (devparam[i].ProtocolIdx)
		{
		case	WEATHER_PROTOCOL:	// 气象
			sprintf(szbuf, "气象");
			srdt.ms_dev[i].IsNeedSerial = 1;
			srdt.ms_dev[i].FirstCmdTimeCnt = get_msec();
			srdt.ms_dev[i].recvdatacnt = 0;
			for (j = 0; j < WEATHER_DATA_NUM; j++)
				srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE;
			break;
		case	RALLY_PROTOCOL:		/* 拉力*/
			sprintf(szbuf, "拉力");
			srdt.ms_dev[i].IsNeedSerial = 1;
			srdt.ms_dev[i].FirstCmdTimeCnt = get_msec();
			srdt.ms_dev[i].recvdatacnt = 0;
			for (j = 0; j < RALLY_DATA_NUM; j++)
				srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE;
			break;
		case	WIND_PROTOCOL:				/* 风速风向*/
			sprintf(szbuf, "风速风向");
			srdt.ms_dev[i].IsNeedSerial = 1;
			srdt.ms_dev[i].FirstCmdTimeCnt = get_msec();
			for (j = 0; j < WEATHER_DATA_NUM; j++)
				srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE;
			break;
		case	SLANT_PROTOCOL:			/* 倾角*/
			sprintf(szbuf, "倾角");
			srdt.ms_dev[i].IsNeedSerial = 1;
			srdt.ms_dev[i].FirstCmdTimeCnt = get_msec();
			srdt.ms_dev[i].recvdatacnt = 0;
			for (j = 0; j < SLANTANGLE_DATA_NUM; j++)
				srdt.ms_dev[i].aiValue[j].AiState = SER_STARTSAMPLE;
			break;
		case	PELCO_D_PROTOCOL:		/* 摄像机协议*/
		case	PELCO_P_PROTOCOL:		/* 摄像机协议*/
		case	SERIALCAMERA_PROTOCOL:	/* 串口摄像机协议*/
			sprintf(szbuf, "摄像机");
			break;
		default:
			srdt.ms_dev[i].IsNeedSerial = 0;
			sprintf(szbuf, "无效传感器");
			break;
		}
		// 测试查询传感器电源状态
#if 0
		LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
		LOGE("3.3V state= %d", getInt(CMD_SET_CAM_3V3_EN_STATE));
		LOGE("485 state=%d", getInt(CMD_SET_485_EN_STATE));

		set12VEnable(true);
		setCam3V3Enable(true);
		setRS485Enable(true);
		sleep(1);
		LOGV("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
		LOGV("3.3V state= %d", getInt(CMD_SET_CAM_3V3_EN_STATE));
		LOGV("485 state=%d", getInt(CMD_SET_485_EN_STATE));
		set12VEnable(false);
		setCam3V3Enable(false);
		setRS485Enable(false);
		sleep(1);
		LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
		LOGE("3.3V state= %d", getInt(CMD_SET_CAM_3V3_EN_STATE));
		LOGE("485 state=%d", getInt(CMD_SET_485_EN_STATE));
#endif
		// 打开传感器电源
		// 打开对应的485电源
		// 打开串口通讯
		memset(logbuf, 0, sizeof(logbuf));
		if (1 == srdt.ms_dev[i].IsNeedSerial)
		{
			sprintf(logbuf, "装置%d, IsNoInsta=%d, 类型：%s", i + 1, devparam[i].IsNoInsta, szbuf);
			DebugLog(8, logbuf, 'I');
			Gm_OpenSensorsPower();
			Gm_OpenSerialPort(i);
		}
	}

	DebugLog(8, "启动数据采样!", 'I');
	/* 直接使用循环进行采样处理*/
	//polltime = get_msec();
	for (;;)
	{
		usleep(10);
		//LOGW("polltime=%ldms", get_msec()-polltime);
		//polltime = get_msec();
		if (GM_SerialTimer() < 0)
		{
			//LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
			DebugLog(8, "退出采样流程!", 'V');
			sleep(5);
			//GM_StartSerialComm();
			break;
		}
	}
	return;
}

#if 1
// 启动使用串口拍照
void GM_StartSerialCameraPhoto(uint8_t channel, int cmdidx)
{
	int 		i, flag = 0;
	char	szbuf[128], logbuf[128];

	srdt.RephotographCnt = 0;
	//FindDevUseSerialCommNo();
#if 0
	//sprintf(szbuf, "sampling=%02X !", srdt.sampling);
	//DebugStringPrintf(szbuf, strlen(szbuf), 1);
	//if(0 == srdt.selfflag)
	//    srdt.selfflag = 1;
	//Gm_OpenSerialPower();
	//Gm_OpenSensorsPower();
	//if(0x00 == srdt.sampling)
	//{
	//    Gm_OpenSerialPort();
	//}
	if (0 == (srdt.sampling & 0x04))
	{
		srdt.sampling |= 4;
		flag = 1;
	}
	if (0x01 == (srdt.sampling & 0x01))
		flag = 0;
#endif
	i = srdt.camerauseserial;
	if ((i < 0) || (i >= MAX_SERIAL_PORT_NUM))
		return;
	serialport[i].Retry = 0;
	serialport[i].RetryTime = 1000;
	serialport[i].WaitTime = 0;
	serialport[i].m_iRevStatus = 0;
	serialport[i].m_iRecvLen = 0;
	serialport[i].m_iNeedRevLength = 0;
	serialport[i].fd = -1;
	memset(serialport[i].m_au8RecvBuf, 0, RECVDATA_MAXLENTH);	// 接收数据缓存区
	ClearCmdFormPollCmdBuf(i);

	// 初始化串口使用状态
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		if (0 == devparam[i].IsNoInsta)
		{
			srdt.ms_dev[i].IsNeedSerial = 0;
			continue;
		}
		memset(szbuf, 0, sizeof(szbuf));
		switch (devparam[i].ProtocolIdx)
		{
		case	SERIALCAMERA_PROTOCOL:		/* 串口摄像机协议*/
		case	PELCO_P_PROTOCOL:		    /* 摄像机协议*/
		case	PELCO_D_PROTOCOL:		    /* 摄像机协议*/
			if ((1 > devparam[i].CameraChannel) || (devparam[i].CameraChannel > MAX_CHANNEL_NUM))
			{
				srdt.ms_dev[i].IsNeedSerial = 0;
				break;
			}
			if (channel == devparam[i].CameraChannel)
			{
				;
			}
			else
				break;
			if (0 == srdt.ms_dev[i].IsNeedSerial)
				srdt.iLastGetPhotoNo = -1;
			else
				srdt.iLastGetPhotoNo = srdt.ms_dev[i].SerialCmdidx;
			srdt.ms_dev[i].IsNeedSerial = 1;
			if (0 == cmdidx)
				srdt.ms_dev[i].image.state = SER_STARTSAMPLE;
			if ((0 == cmdidx) && (srdt.presetno > 0))
			{
				srdt.ms_dev[i].SerialCmdidx = 10017;
				srdt.iLastGetPhotoNo = cmdidx;
			}
			else
				srdt.ms_dev[i].SerialCmdidx = cmdidx;
			srdt.ms_dev[i].FirstCmdTimeCnt = get_msec();
			srdt.sendphotocmdcnt = 0;
			sprintf(szbuf, "摄像机");
			flag = 1;
			break;
		default:
			if (1 == srdt.ms_dev[i].IsNeedSerial)
				break;
			srdt.ms_dev[i].IsNeedSerial = 0;
			break;
		}
		if (1 == srdt.ms_dev[i].IsNeedSerial)
		{
			sprintf(logbuf, "装置%d, IsNoInsta=%d, 类型：%s", i + 1, devparam[i].IsNoInsta, szbuf);
			DebugLog(8, logbuf, 'I');
			Gm_OpenSensorsPower();
			Gm_OpenSerialPort(i);
		}
	}
	if (0x01 == flag)
	{
		sprintf(szbuf, "摄像机启动串口定时器!");
		DebugLog(8, szbuf, 'I');
		for (;;)
		{
			usleep(10);
			//LOGW("polltime=%ldms", get_msec()-polltime);
			//polltime = get_msec();
			if (GM_SerialTimer() < 0)
			{
				//LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
				DebugLog(8, "退出拍照流程！", 'V');
				sleep(3);
				break;
			}
		}
	}
	//return;
}
#endif

int GM_SerialTimer(void)
{
	int flag = -1;

	GM_AllSerialComRecv();
	GM_IsCloseSensors();
	Gm_FindAllSensorsCommand();
	GM_AllSerialComRecv();
	flag = GM_CloseTimer();
	return  flag;
}

/********************************************************************************
函数名称: void Gm_FindAllSensorsCommand()
功能说明:轮询所有串口和传感器是否需要生成下发命令
输入参数:
输出参数:
其它说明:
*********************************************************************************/
void Gm_FindAllSensorsCommand()
{
	int i, j, curidx, flag;

	//Gm_CheckSensorsPower();  /* 暂时不考虑电源控制*/
	for (j = 0; j < MAX_SERIAL_PORT_NUM; j++)
	{
		// 发送缓冲区中命令 接收到了应答报文，紧接着进行缓冲区清理
		SendCmdFormPollCmdBuf(j);
		// 串口已经被占用则直接跳过
		curidx = srdt.curdevidx[j];
		for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
		{
			curidx = (curidx + 1) % MAX_SERIAL_DEV_NUM;
			if (j != devparam[curidx].commid)
				continue;
			if (srdt.ms_dev[curidx].IsNeedSerial == 0)
				continue;
			if (serialport[devparam[curidx].commid].fd < 0)
				Gm_OpenSerialPort(curidx);
			if (serialport[devparam[curidx].commid].cmdlen > 0)
				break;
			//LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE));
			//LOGE("3.3V state= %d", getInt(CMD_SET_CAM_3V3_EN_STATE));
			//LOGE("485 state=%d", getInt(CMD_SET_485_EN_STATE));


			flag = -1;
			switch (devparam[curidx].ProtocolIdx)
			{
			case 	WEATHER_PROTOCOL:		/* 温湿度气压*/
			case	RALLY_PROTOCOL:		    /* 拉力*/
			case	WIND_PROTOCOL:				/* 风速风向*/
			case	SLANT_PROTOCOL:	/* 倾角*/
				flag = FindNextShxyProtocolCommand(curidx);
				break;
			case	RESERVE2_PROTOCOL:
				break;
			case	RESERVE5_PROTOCOL:
				break;
			case	PELCO_D_PROTOCOL:		/* 摄像机协议*/
			case	PELCO_P_PROTOCOL:		/* 摄像机协议*/
			case	SERIALCAMERA_PROTOCOL:	/* 串口摄像机协议*/
				flag = FindNextCameraPhotoCommand(curidx);
				break;
				break;
			}
			if (flag == -1)
				continue;
			srdt.curdevidx[j] = curidx;
			break;
		}
		// 发送缓冲区中命令 生成了命令之后紧接着进行命令发送
		SendCmdFormPollCmdBuf(j);
	}
}

/********************************************************************************
函数名称: void GM_IsCloseSensors()
功能说明:检查所有传感器是否采集完毕，采集完毕的关闭传感器电源
输入参数:
输出参数:
其它说明:
*********************************************************************************/
void GM_IsCloseSensors()
{
	int		i, j;
	char		buf[256];
	int64_t    lctime;

	lctime = get_msec();
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		if (srdt.ms_dev[i].IsNeedSerial == 0)
			continue;
		memset(buf, 0, sizeof(buf));
		switch (devparam[i].ProtocolIdx)
		{
		case 	WEATHER_PROTOCOL:		/* 气象*/
		case	RALLY_PROTOCOL:		    /* 拉力*/
		case	WIND_PROTOCOL:			/* 风速风向*/
		case	SLANT_PROTOCOL:			/* 倾角*/
			if ((lctime - srdt.ms_dev[i].FirstCmdTimeCnt > 50 * 1000) || (lctime - srdt.ms_dev[i].FirstCmdTimeCnt < 0))
			{
				srdt.ms_dev[i].FirstCmdTimeCnt = lctime;
				break;
			}
			if (lctime - srdt.ms_dev[i].FirstCmdTimeCnt > 15 * 1000)
			{
				srdt.ms_dev[i].IsNeedSerial = 0;
				// 关闭传感器电源
				sprintf(buf, "读取装置%d数据%0.3f秒，关闭装置%d电源!", i + 1, (get_msec() - srdt.ms_dev[i].FirstCmdTimeCnt) / 1000.0, i + 1);
				DebugLog(devparam[i].commid, buf, 'I');
				for (j = 0; j < MAX_DEV_VALUE_NUM; j++)
				{
					if (SER_STARTSAMPLE == srdt.ms_dev[i].aiValue[j].AiState)
						srdt.ms_dev[i].aiValue[j].AiState = SER_SAMPLEFAIL;
					else if (SER_SAMPLE == srdt.ms_dev[i].aiValue[j].AiState)
						srdt.ms_dev[i].aiValue[j].AiState = SAMPLINGSUCCESS;
				}
				for (j = 0; j < WEATHER_DATA_NUM; j++)
				{
					if (SER_STARTSAMPLE == weatherpntmsg[j].AiState)
						weatherpntmsg[j].AiState = SER_SAMPLEFAIL;
					else if (SER_SAMPLE == weatherpntmsg[j].AiState)
						weatherpntmsg[j].AiState = SAMPLINGSUCCESS;
				}
			}
			break;
		case	PELCO_D_PROTOCOL:	/* 摄像机类型*/
		case	PELCO_P_PROTOCOL:	/* 摄像机类型*/
		case	SERIALCAMERA_PROTOCOL:	/* 串口摄像机协议*/
			if (-1 == srdt.ms_dev[i].SerialCmdidx)
			{
				if ((SER_STARTSAMPLE == srdt.ms_dev[i].image.state) || (SER_SAMPLE == srdt.ms_dev[i].image.state))
					srdt.ms_dev[i].image.state = SER_SAMPLEFAIL;
				else if (PHOTO_SAVE_SUCC == srdt.ms_dev[i].image.state)
					srdt.ms_dev[i].image.state = SAMPLINGSUCCESS;
				srdt.ms_dev[i].IsNeedSerial = 0;
				sprintf(buf, "通道%d摄像机使用完毕!可以关闭摄像机电源!", devparam[i].CameraChannel);
				DebugLog(devparam[i].commid, buf, 'I');
			}
			break;
		}
	}
}

/********************************************************************************
函数名称: void GM_AllSerialComRecv()
功能说明:检查所有串口是否有数据接收，有则启动接收
输入参数:
输出参数:
其它说明:
*********************************************************************************/
void GM_AllSerialComRecv()
{
	int	i, j, recvlen;
	u_char	recvbuf[RECVDATA_MAXLENTH];
	char		buf[256];

	for (j = 0; j < MAX_SERIAL_PORT_NUM; j++)
	{
		memset(recvbuf, 0, sizeof(recvbuf));
		if (serialport[j].fd <= 0)
			continue;
		//for(;;)
		recvlen = read(serialport[j].fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */

		if (recvlen < 1)
			continue;
#if 1
		sprintf(buf, "收到串口%d, %d字节数据:", j + 1, recvlen);
		BytestreamLOG(j, buf, recvbuf, recvlen, 'I');
#endif

		SerialDataProcess(srdt.curdevidx[j], recvbuf, recvlen);
	}
}

/********************************************************************************
函数名称: int GM_CloseTimer()
功能说明:
输入参数:
输出参数:
其它说明:
*********************************************************************************/
int GM_CloseTimer()
{
	int		i, j, iretime;
	char		buf[256];

	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		if ((srdt.ms_dev[i].IsNeedSerial == 1)
			&& ((0 < devparam[i].ProtocolIdx) && (INVALID_PROTOCOL > devparam[i].ProtocolIdx)))
			break;
	}
	if (i < MAX_SERIAL_DEV_NUM)
	{
		return 1; // 寻找
	}
	else		// 关闭所有串口及电源
	{
		Gm_CloseSerialPort();
		for (j = 0; j < MAX_SERIAL_DEV_NUM; j++)
			Gm_CloseSensorsPower();
		for (j = 0; j < MAX_SERIAL_PORT_NUM; j++)
			ClearCmdFormPollCmdBuf(j);
		sprintf(buf, "关闭串口定时器!");
		DebugLog(8, buf, 'I');
		return -1;
	}
}

void SerialDataProcess(int devidx, u_char *buf, int len)
{
	switch (devparam[devidx].ProtocolIdx)
	{

	case 	WEATHER_PROTOCOL:		/* 气象*/
	case	RALLY_PROTOCOL:		/* 拉力*/
	case	WIND_PROTOCOL:				/* 风速风向*/
	case	SLANT_PROTOCOL:			/* 倾角*/
		ShxyProtocolRecvData(devidx, buf, len);
		break;
	case	RESERVE2_PROTOCOL:			/* 意科电池电量读取协议*/
		break;
	case	PELCO_D_PROTOCOL:		/* 摄像机协议*/
	case	PELCO_P_PROTOCOL:		/* 摄像机协议*/
	case	SERIALCAMERA_PROTOCOL:	/* 串口摄像机协议*/
		CameraRecvData(devidx, buf, len);
		break;
	}
}

void DebugLog(int commid, char *szbuf, char flag)
{
	if (NULL == szbuf)
		return;
	SaveLogTofile(commid, szbuf);
	switch (flag)
	{
	case 'E':
		ALOGE("%s", szbuf);
		break;
	case 'I':
		ALOGI("%s", szbuf);
		break;
	case 'D':
		ALOGD("%s", szbuf);
		break;
	case 'V':
		ALOGI("%s", szbuf);
		break;
	case 'W':
		ALOGW("%s", szbuf);
		break;
	default:
		ALOGI("%s", szbuf);
		break;
	}
}

int SaveLogTofile(int commid, char *szbuf)
{
	int             status;
	time_t          now;
	char            filename[512], filedir[512], buf[128];
	FILE            *fp = NULL;
	struct tm       t0;
	struct timeval tv;

	if (NULL == szbuf)
		return -1;

	now = time(NULL);
	localtime_r(&now, &t0);
	gettimeofday(&tv, NULL);

	memset(filedir, 0, sizeof(filedir));
	sprintf(filedir, "/sdcard/log/");

	if (access(filedir, 0) == 0)
		;//LOGI("文件路径已经存在！");
	else
	{
		status = mkdir(filedir, S_IRWXU | S_IRWXG | S_IRWXO);
		if (status < 0)
			return -1;
	}
	// 写入文件到sdcard
	memset(filename, 0, sizeof(filename));
	sprintf(filename, "%s%d-%d-%d-COM%d.log", filedir, t0.tm_year + 1900, t0.tm_mon + 1, t0.tm_mday, commid + 1);
	fp = fopen(filename, "a+");
	if (NULL == fp)
		return -1;
	memset(buf, 0, sizeof(buf));
	sprintf(buf, "%d-%d-%d %d:%d:%d-%d ", t0.tm_year + 1900, t0.tm_mon + 1, t0.tm_mday, t0.tm_hour, t0.tm_min, t0.tm_sec, tv.tv_usec / 1000);
	fwrite(buf, 1, strlen(buf), fp);
	fwrite(szbuf, 1, strlen(szbuf), fp);
	memset(buf, 0, sizeof(buf));
	sprintf(buf, "\n");
	fwrite(buf, 1, strlen(buf), fp);

	fclose(fp);
	return 1;
}

int SaveImageDataTofile(int devno)
{
	u_char          *image = NULL, *tempphoto = NULL;
	int             i, status;
	size_t          len;
	char            filename[512]/*, filedir[512]*/, szbuf[128];
	FILE            *fp = NULL;
	SERIAL_DEV_DEF	*pPortParam;

	pPortParam = &srdt.ms_dev[devno];
	image = (u_char*)malloc(pPortParam->image.imagelen);
	if (NULL == image)
		return -1;
	tempphoto = image;
	for (i = 0; i < pPortParam->image.imagenum; ++i) {
		memmove(tempphoto, &pPortParam->image.buf[i], (size_t)pPortParam->image.ilen[i]);
		tempphoto += (size_t)pPortParam->image.ilen[i];
	}

	memset(szbuf, 0, sizeof(szbuf));
	//memset(filedir, 0, sizeof(filedir));
	//sprintf(filedir, "/sdcard/photo/");

	if (access(srdt.filedir, 0) == 0)
	{
		sprintf(szbuf, "文件路径%s已经存在！", srdt.filedir);
		DebugLog(devparam[devno].commid, szbuf, 'I');
	}
	else
	{
		status = mkdir(srdt.filedir, S_IRWXU | S_IRWXG | S_IRWXO);
		if (status < 0)
			return -1;
	}
	// 写入文件到sdcard
	memset(pPortParam->image.photoname, 0, sizeof(pPortParam->image.photoname));
	sprintf(pPortParam->image.photoname, "%s%d-%d-%d.jpg", srdt.filedir, devparam[devno].CameraChannel, pPortParam->image.presetno, pPortParam->image.phototime);
	fp = fopen(pPortParam->image.photoname, "wb+");
	if (NULL == fp)
		return -1;
	len = fwrite(image, 1, pPortParam->image.imagelen, fp);
	fclose(fp);
	free(image);
	image = NULL;
	if (len < pPortParam->image.imagelen)
		return -1;
	else
	{
		memset(szbuf, 0, sizeof(szbuf));
		sprintf(szbuf, "写入图片文件%s成功！", pPortParam->image.photoname);
		DebugLog(devparam[devno].commid, szbuf, 'I');
		return 1;
	}
}

/*******************************************************************
*    		        读 摄像机 数据				                   *
*******************************************************************/
void CameraRecvData(int devno, u_char *buf, int len)
{
	int  				i;
	SIO_PARAM_SERIAL_DEF *pPortParam;

	if ((devno < 0) || (devno > MAX_SERIAL_DEV_NUM))
	{
		return;
	}
	pPortParam = &serialport[devparam[devno].commid];

	for (i = 0; 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];
			pPortParam->m_iRevStatus++;
			pPortParam->m_iNeedRevLength = pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] * 256 + buf[i] + 5;
			break;
		case 3:			// 0x68
			pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
			pPortParam->m_iNeedRevLength--;
			if (0x68 == buf[i])
				pPortParam->m_iRevStatus++;
			else
				pPortParam->m_iRevStatus = 18;
			break;
		case 4:	// 正确接收数据
			pPortParam->m_iNeedRevLength--;
			pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
			if (pPortParam->m_iNeedRevLength > 0)
				break;
			if (buf[i] != 0x16)
			{
				pPortParam->m_iRevStatus = 18;
				break;
			}

			if (pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] ==
				CalLpc(&pPortParam->m_au8RecvBuf[4], pPortParam->m_iRecvLen - 6))
			{
				CameraPhotoPortDataProcess(devno);
				pPortParam->m_iRevStatus = 0;
				pPortParam->RevCmdFlag = 1;
			}
			else
			{
				pPortParam->m_iRevStatus = 0;
			}
			pPortParam->m_iRecvLen = 0;
			break;
		case 255:// 错误接收数据
		default:
			if (buf[i] == 0x68)
			{
				pPortParam->m_iRevStatus = 1;
				pPortParam->m_iRecvLen = 1;
				pPortParam->m_au8RecvBuf[0] = buf[i];
			}
			else if (buf[i] == 0x16)
			{
				pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
				pPortParam->m_iRevStatus = 0;
				pPortParam->m_iRecvLen = 0;
			}
			else
			{
				pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
				if (pPortParam->m_iRecvLen > 200)
				{
					pPortParam->m_iRecvLen = 0;
				}
			}
			break;
		}
	}
}

/*********************************************************************************
				CameraPhoto 端口数据处理
**********************************************************************************/
void CameraPhotoPortDataProcess(int devno)
{
	RTUMSG		rtumsg;
	SERIAL_DEV_DEF	*pPortParam;
	SIO_PARAM_SERIAL_DEF *curserial;
	int img_file_size, packetnum, iNo, packsize, i = 0, presetno, iphototime, pidx;
	char			szbuf[128];
	uint16_t		uDevAddr;
	uint8_t			cmdidx, recvend;

	pPortParam = &srdt.ms_dev[devno];
	curserial = &serialport[devparam[devno].commid];

	memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData));
	memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen);
	rtumsg.MsgLen = curserial->m_iRecvLen;
	rtumsg.PortIdx = devparam[devno].commid;
	cmdidx = curserial->m_au8RecvBuf[5];
	uDevAddr = curserial->m_au8RecvBuf[4];

	//sprintf(szbuf, "摄像机地址%d,命令%02X!", uDevAddr, cmdidx);
	//DebugStringPrintf(szbuf, strlen(szbuf), 1);
	if (uDevAddr != devparam[devno].devaddr)
		return;
	memset(szbuf, 0, sizeof(szbuf));
	switch (cmdidx)
	{
	case	0x10:		/* 拍照应答*/
		if (0xFF == rtumsg.MsgData[6])
		{
			srdt.RephotographCnt++;
			if (srdt.RephotographCnt > 2)
			{
				pPortParam->SerialCmdidx = -1;
				sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!", srdt.RephotographCnt);
				DebugLog(devparam[devno].commid, szbuf, 'E');
			}
			break;
		}
		i = 6;
		memset(&pPortParam->image, 0, sizeof(pPortParam->image));
		iphototime = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24);
		srdt.photographtime = iphototime;
		pPortParam->image.phototime = iphototime;
		i = 10;
		img_file_size = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24);
		packetnum = rtumsg.MsgData[i + 5] + (rtumsg.MsgData[i + 4] << 8);
		pPortParam->image.imagelen = img_file_size;
		pPortParam->image.imagenum = packetnum;
		srdt.imagepacketnum = packetnum;
		srdt.historyimagenum[devparam[devno].CameraChannel - 1] = rtumsg.MsgData[i + 7] + (rtumsg.MsgData[i + 6] << 8);
		sprintf(szbuf, "有%d张历史图片!", srdt.historyimagenum[devparam[devno].CameraChannel - 1]);
		DebugLog(devparam[devno].commid, szbuf, 'V');
		presetno = (int)rtumsg.MsgData[i + 8];
		pPortParam->image.presetno = presetno;
		pPortParam->image.state = SER_SAMPLE;
		curserial->RevCmdFlag = 1;
		pPortParam->SerialCmdidx = 1;
		srdt.sendphotocmdcnt = 0;
		break;
	case	0x11:		/* 图片数据包*/
		i = 6;
		iNo = rtumsg.MsgData[i + 1] + rtumsg.MsgData[i] * 256;
		packsize = rtumsg.MsgData[i + 3] + rtumsg.MsgData[i + 2] * 256;
		memmove(&pPortParam->image.buf[iNo - 1], &rtumsg.MsgData[i + 4], packsize);
		pPortParam->image.ilen[iNo - 1] = packsize;
		sprintf(szbuf, "收到第%d(总%d包)包长=%d", iNo, srdt.imagepacketnum, packsize);
		DebugLog(devparam[devno].commid, szbuf, 'V');
		curserial->RevCmdFlag = 1;
		pPortParam->FirstCmdTimeCnt = get_msec();
		if ((iNo == pPortParam->SerialCmdidx) && (0xFF > rtumsg.MsgData[i + 2]))
		{
			if (iNo == srdt.imagepacketnum)
			{   /* 检查是否有漏包*/
				for (pidx = 0; pidx < srdt.imagepacketnum; pidx++)
				{
					if (pPortParam->image.ilen[pidx] < 1)
						break;
				}
				if (pidx < srdt.imagepacketnum)
				{
					iNo = pidx;
					recvend = 0;
				}
				else
				{
					if ((1 == SaveImageDataTofile(devno)) && (SER_SAMPLE == pPortParam->image.state))
						pPortParam->image.state = PHOTO_SAVE_SUCC;
					recvend = 1;
				}
			}
			else
				recvend = 0;

			if (packsize > MAX_PHOTO_FRAME_LEN)
				recvend = 0xFF;

			if (1 == recvend)
			{
				pPortParam->SerialCmdidx = 10002;/* 图片读取完成*/
				//pPortParam->image.lastlen = packsize;
			}
			else if (0xFF == recvend)
			{
				pPortParam->SerialCmdidx = -1;
			}
			else
			{
				if ((iNo > srdt.imagepacketnum) || (0 >= srdt.imagepacketnum))
				{
					pPortParam->SerialCmdidx = -1;
				}
				else
					pPortParam->SerialCmdidx = iNo + 1;
			}
			srdt.errorPhotoNoCnt = 0;
			break;
		}
		srdt.errorPhotoNoCnt++;
		sprintf(szbuf, "问询第%d包图片摄像机应答第%d包,连续错误%d次!",
			pPortParam->SerialCmdidx, iNo, srdt.errorPhotoNoCnt);
		DebugLog(devparam[devno].commid, szbuf, 'E');
		if (srdt.errorPhotoNoCnt > 5)
		{
			pPortParam->SerialCmdidx = 0;
			srdt.RephotographCnt++;
			if (srdt.RephotographCnt > 2)
			{
				pPortParam->SerialCmdidx = -1;
				sprintf(szbuf, "因摄像机重拍%d次均未成功!结束拍照!", srdt.RephotographCnt);
				DebugLog(devparam[devno].commid, szbuf, 'E');
			}
		}
		break;
	case	0x03:
		sprintf(szbuf, "设置波特率%d成功", devparam[devno].baudrate);
		DebugLog(devparam[devno].commid, szbuf, 'D');
		pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		curserial->RevCmdFlag = 1;
		pPortParam->FirstCmdTimeCnt = get_msec();
		break;
	case	0x15:
		if (0xFF == rtumsg.MsgData[6])
		{
			pPortParam->SerialCmdidx = -1;
			sprintf(szbuf, "没有历史图片!结束读取图片!");
			DebugLog(devparam[devno].commid, szbuf, 'I');
			break;
		}
		i = 6;
		iphototime = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24);
		srdt.photographtime = iphototime;
		pPortParam->image.phototime = iphototime;
		i = 10;
		img_file_size = rtumsg.MsgData[i + 3] + (rtumsg.MsgData[i + 2] << 8) + (rtumsg.MsgData[i + 1] << 16) + (rtumsg.MsgData[i] << 24);
		packetnum = rtumsg.MsgData[i + 5] + (rtumsg.MsgData[i + 4] << 8);
		pPortParam->image.imagelen = img_file_size;
		pPortParam->image.imagenum = packetnum;
		srdt.imagepacketnum = packetnum;
		srdt.historyimagenum[devparam[devno].CameraChannel - 1] = rtumsg.MsgData[i + 7] + (rtumsg.MsgData[i + 6] << 8);
		presetno = rtumsg.MsgData[i + 8];
		pPortParam->image.presetno = presetno;
		sprintf(szbuf, "读取历史图片,还有%d张历史图片!", srdt.historyimagenum[devparam[devno].CameraChannel - 1]);
		DebugLog(devparam[devno].commid, szbuf, 'I');
		curserial->RevCmdFlag = 1;
		pPortParam->SerialCmdidx = 1;
		srdt.sendphotocmdcnt = 0;
		break;
	case	0x16:
		if (0xFF == rtumsg.MsgData[10])
		{
			pPortParam->SerialCmdidx = -1;
			sprintf(szbuf, "摄像机图片保存失败!");
			DebugLog(devparam[devno].commid, szbuf, 'E');
		}
		pPortParam->SerialCmdidx = -1;
		if (0 == rtumsg.MsgData[10])
		{
			if (0 == srdt.historyimagenum[devparam[devno].CameraChannel - 1])
			{
				;
			}
			else
			{
				pPortParam->SerialCmdidx = 10003;/* 暂时不实现*/
			}
		}
		pPortParam->FirstCmdTimeCnt = get_msec();
		curserial->RevCmdFlag = 1;
		break;
	default:
		curserial->RevCmdFlag = 1;
		break;
	}
}

/*********************************************************************************
							发送命令
**********************************************************************************/
void SendCmdFormPollCmdBuf(int port)
{
	char			buf[128];
	int				len, ret;
	int64_t            lctime;
	SIO_PARAM_SERIAL_DEF 	*pPortParam;

	pPortParam = &serialport[port];
	memset(buf, 0, sizeof(buf));
	lctime = get_msec();
	if (pPortParam->ForceWaitFlag && pPortParam->ForceWaitCnt)
	{
		pPortParam->ForceWaitCnt--;
		return;
	}

	if (pPortParam->SendCmdFlag && (pPortParam->RevCmdFlag == 0))
	{
		//pPortParam->RetryTimeCnt++;
		if ((lctime - pPortParam->RetryTimeCnt > 3 * pPortParam->RetryTime) || (lctime - pPortParam->RetryTimeCnt < 0))
		{
			pPortParam->RetryTimeCnt = lctime;
			return;
		}
		if (lctime - pPortParam->RetryTimeCnt < pPortParam->RetryTime)
			//if(pPortParam->RetryTimeCnt < pPortParam->RetryTime)
		{
			return;
		}
		pPortParam->RetryTimeCnt = lctime;
		pPortParam->RetryCnt++;
		if (pPortParam->RetryCnt > pPortParam->Retry)
		{
			ClearCmdFormPollCmdBuf(port);
		}
		else
		{
			pPortParam->SendCmdFlag = 0;
			pPortParam->RevCmdFlag = 0;
			pPortParam->ReSendCmdFlag = 1;
		}
	}

	if (pPortParam->SendCmdFlag && pPortParam->RevCmdFlag)
	{
		// 清除当前命令
		ClearCmdFormPollCmdBuf(port);
	}

	if (pPortParam->WaitTime > 0)
	{
		if ((lctime - pPortParam->WaitTimeCnt > 30 * pPortParam->WaitTime) || (lctime - pPortParam->WaitTimeCnt < 0))
		{
			pPortParam->WaitTimeCnt = lctime;
			return;
		}

		if (lctime - pPortParam->WaitTimeCnt < pPortParam->WaitTime)
		{
			return;
		}
	}
	pPortParam->WaitTimeCnt = lctime;

	if (pPortParam->ReSendCmdFlag)
		len = pPortParam->cmdlen;
	else
	{
		len = pPortParam->cmdlen;
		pPortParam->RetryCnt = 0;
	}
	if (len == 0)
		return;

	serialport[devparam[srdt.curdevidx[port]].commid].m_iRecvLen = 0;	// 当发送一条新指令时，清除接收状态
	serialport[devparam[srdt.curdevidx[port]].commid].m_iRevStatus = 0;
	if (serialport[port].fd < 0)
		return;
	ret = Gm_SetSerialPortParam(port);
	if (ret < 0)
		return;
	len = GM_SerialComSend(&pPortParam->PollCmd[2], pPortParam->cmdlen - 2, port);
	if (len < 1)
	{
		sprintf(buf, "串口%d, 发送命令失败!", port + 1);
		DebugLog(port, buf, 'E');
	}
	else
	{

		sprintf(buf, "发送串口%d 装置%d命令:", port + 1, srdt.curdevidx[port] + 1);
		BytestreamLOG(port, buf, &pPortParam->PollCmd[2], len, 'D');
		sprintf(buf, "sendtimeconst= %lld", lctime - pPortParam->lsendtime);
		DebugLog(port, buf, 'W');
		pPortParam->lsendtime = lctime;
	}
	pPortParam->SendCmdFlag = 1;
	pPortParam->ReSendCmdFlag = 0;
	pPortParam->RevCmdFlag = 0;
	pPortParam->RetryTimeCnt = lctime;

	pPortParam->ForceWaitCnt = pPortParam->PollCmd[0] * 256 + pPortParam->PollCmd[1] + TIMER_CNT - 1;
	pPortParam->ForceWaitCnt /= TIMER_CNT;
	if (pPortParam->ForceWaitCnt)
	{
		pPortParam->ForceWaitFlag = 1;
	}
}

void ClearCmdAllFlag(int commid)
{
	if ((commid < 0) || (commid >= MAX_SERIAL_PORT_NUM))
		return;

	serialport[commid].RetryCnt = 0;
	serialport[commid].RetryTimeCnt = get_msec();
	serialport[commid].WaitTimeCnt = get_msec();
	serialport[commid].ForceWaitFlag = 0;
	serialport[commid].ForceWaitCnt = 0;
	serialport[commid].SendCmdFlag = 0;
	serialport[commid].RevCmdFlag = 0;
	serialport[commid].ReSendCmdFlag = 0;
}

void ClearCmdFormPollCmdBuf(int port)
{
	//int		len, idx;
	SIO_PARAM_SERIAL_DEF 	*pPortParam;

	if ((port < 0) || (port >= MAX_SERIAL_PORT_NUM))
		return;
	pPortParam = &serialport[port];

	pPortParam->cmdlen = 0;
	memset(pPortParam->PollCmd, 0, sizeof(pPortParam->PollCmd));
	srdt.serialstatus[port] = 0;
	// 清除指令下发标识
	ClearCmdAllFlag(port);
}

// 下发串口拍照指令控制
int FindNextCameraPhotoCommand(int devidx)
{
	int	imagesize = 3, cmdno;
	uint8_t	channel, imagequality = 90, presetno;
	uint16_t	packetsize;
	int64_t    lcurtime;
	uint8_t	cmdidx = 0x10;
	char		szbuf[128];

	//如果命令缓冲区仍有命令，则退出本函数
	if ((devparam[devidx].commid + 1 < 1) || (devparam[devidx].commid + 1 > MAX_SERIAL_PORT_NUM))
		return -1;
	// if(serialport[devparam[devidx].commid].cmdlen > 0)
	  //   return -1;
	if (-1 == srdt.ms_dev[devidx].SerialCmdidx)/* 下发拍照指令*/
		return -1;
	channel = devparam[devidx].CameraChannel;
	if ((1 > channel) || (channel > MAX_CHANNEL_NUM))
	{
		/* 通道号错误退出拍照流程*/;
		srdt.ms_dev[devidx].SerialCmdidx = -1;
		sprintf(szbuf, "装置配置中，通道号配置错误!结束拍照!");
		DebugLog(devparam[devidx].commid, szbuf, 'I');
	}
	cmdno = srdt.ms_dev[devidx].SerialCmdidx;
	lcurtime = get_msec();
	if ((1 > cmdno) || (10000 <= cmdno)) {
		if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 300)
			return -1;
	}
	switch (cmdno)
	{
	case 0:/* 下发拍照指令*/
		if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 3800)
			return -1;
		if ((lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 3 * 35 * 1000) || (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt < 0))
		{
			srdt.ms_dev[devidx].FirstCmdTimeCnt = lcurtime;
			return -1;
		}

		if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 35 * 1000)
		{
			srdt.ms_dev[devidx].SerialCmdidx = -1;
			sprintf(szbuf, "串口摄像机未接或故障!结束拍照!");
			DebugLog(devparam[devidx].commid, szbuf, 'I');
			return -1;
		}
		memset(szbuf, 0, sizeof(szbuf));
		sprintf(szbuf, "time=%lldms", lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt);
		DebugLog(devparam[devidx].commid, szbuf, 'I');
		packetsize = (uint16_t)MAX_PHOTO_FRAME_LEN;
		srdt.sendphotocmdcnt++;
		srdt.imagepacketnum = 0;
		srdt.errorPhotoNoCnt = 0;
		cmdidx = 0x10;
		imagesize = srdt.bImageSize;
		break;

	case 10000: /* 下发设置串口波特率命令*/
		switch (devparam[devidx].baudrate)
		{
		case	B9600:
			imagesize = 0x07;
			break;
		case	B19200:
			imagesize = 0x08;
			break;
		case	B38400:
			imagesize = 0x09;
			break;
		default:
			sprintf(szbuf, "设置串口摄像机参数时，配置参数错误!退出设置!");
			DebugLog(devparam[devidx].commid, szbuf, 'I');
			srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
			srdt.iLastGetPhotoNo = -1;
			return -1;
		}

		if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 15 * 1000)
		{
			srdt.ms_dev[devidx].SerialCmdidx = -1;
			sprintf(szbuf, "设置串口摄像机参数时，15秒未收到摄像机应答!退出设置!");
			DebugLog(devparam[devidx].commid, szbuf, 'I');
			return -1;
		}
		cmdidx = 0x03;
		packetsize = 0xFFFF;
		break;

	case 10001: /* 通知摄像机图片读取完成或存储（16H）*/
	case 10002:
		cmdidx = 0x16;
		if (10001 == cmdno)
			packetsize = 1;
		else
			packetsize = 0;
		imagesize = srdt.photographtime;	/* 需要保存或删除的图片拍摄时间*/
		break;

	case 10003:     		/* 读取历史图片（15H）*/
		cmdidx = 0x15;
		packetsize = (uint16_t)MAX_PHOTO_FRAME_LEN;
		break;

	case 10005:     /* 关闭功能*/
		//Gm_CtrlPtzCmd(1, P_MOVE_LEFT);
		//sleep(2);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		//sleep(20);
		return 1;
	case 10006:     /* 自动扫描功能控制(1/0 打开/关闭该功能)*/
		Gm_CtrlPtzCmd(channel, P_Auto_Scan);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10007:     /* 光圈缩小(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_IRIS_CLOSE);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10008:     /* 光圈放大(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_IRIS_OPEN);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10009:     /* 近距离聚焦(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_FOCUS_NEAR);
		usleep(100000);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10010:     /* 远距离聚焦(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_FOCUS_FAR);
		usleep(100000);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10011:     /* 远离物体(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_ZOOM_WIDE);
		usleep(100000);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10012:     /* 接近物体(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_ZOOM_TELE);
		usleep(100000);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10013:     /* 向下移动镜头(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_MOVE_DOWN);
		sleep(1);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10014:     /* 向上移动镜头(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_MOVE_UP);
		sleep(1);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10015:     /* 向左移动镜头(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_MOVE_LEFT);
		sleep(1);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10016:     /* 向右移动镜头(1 有效)*/
		Gm_CtrlPtzCmd(channel, P_MOVE_RIGHT);
		sleep(1);
		Gm_CtrlPtzCmd(channel, Cmd_Cancel);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	case 10017:     /* 调用预置点*/
		//srdt.presetno = 2;
		Gm_CtrlPtzCmd(channel, MOVE_TO_PRESETNO + srdt.presetno);
		sleep(2);
		if (0 == srdt.IsSleep)
		{
			srdt.ms_dev[devidx].SerialCmdidx = 10017;
			srdt.IsSleep++;
			return 1;
		}
		//if(srdt.presetno > 1)
		 //   srdt.presetno = 1;
	   // else
		 //   srdt.presetno++;
		//srdt.ms_dev[devidx].SerialCmdidx = -1;
		//Gm_CtrlPtzCmd(channel, MOVE_TO_PRESETNO+srdt.presetno);
		//usleep(1000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		srdt.IsSleep = 0;
		return 1;
	case 10018:     /* 设置预置点*/
		Gm_CtrlPtzCmd(channel, SET_PRESETNO + srdt.presetno);
		usleep(100000);
		srdt.ms_dev[devidx].SerialCmdidx = srdt.iLastGetPhotoNo;
		srdt.iLastGetPhotoNo = -1;
		return 1;
	default:
		imagesize = 0xFF;
		packetsize = (uint16_t)srdt.ms_dev[devidx].SerialCmdidx;
		cmdidx = 0x11;
#if 0
		if (0 == srdt.IsSleep)
		{
			srdt.IsSleep++;
			testComm();
		}
#endif
		if (lcurtime - srdt.ms_dev[devidx].FirstCmdTimeCnt > 35 * 1000)
		{
			srdt.ms_dev[devidx].SerialCmdidx = -1;
			sprintf(szbuf, "读取第%d包图片数据35秒未收到!结束拍照!", packetsize);
			DebugLog(devparam[devidx].commid, szbuf, 'I');
			return -1;
		}
		break;
	}
	MakeCameraPhotoCommand(devidx, cmdidx, imagesize, packetsize, imagequality, srdt.sendphototime);
	//MakeCameraPhotoCommand(devidx, 2, imagesize, packetsize, imagequality);
	srdt.curdevidx[devparam[devidx].commid] = devidx;
	return 1;
}

/*********************************************************************************
					生成 CameraPhoto命令
**********************************************************************************/
void MakeCameraPhotoCommand(int portno, uint8_t cmdidx, int OneParam, uint16_t TwoParam, uint8_t Threep, int phototime)
{
	int			i, icurtime;
	u_char		*sendbuf;
	//char			szbuf[128];

	sendbuf = serialport[devparam[portno].commid].PollCmd;

	icurtime = phototime;
	i = 0;
	sendbuf[i++] = 0x00;		/* 强制等待时间*/
	sendbuf[i++] = 0x00;		/* 强制等待时间*/
	sendbuf[i++] = 0x68;			/* 起始字符*/
	sendbuf[i++] = (uint8_t)0x00;		/* length	*/
	sendbuf[i++] = (uint8_t)0x00;		/* length	*/
	sendbuf[i++] = 0x68;			/* 起始字符*/
	sendbuf[i++] = (uint8_t)devparam[portno].devaddr;/* 传感器地址*/
	sendbuf[i++] = cmdidx;		/* 命令字*/
	switch (cmdidx)
	{
	case    0x02:   /* */
		sendbuf[i - 2] = 0xFF;
		break;
	case	0x03:	/*设置传感器通讯参数（03H）*/
		sendbuf[i++] = 0x00;	/* 波特率*/
		sendbuf[i++] = 0x00;
		sendbuf[i++] = 0x00;
		sendbuf[i++] = (uint8_t)OneParam;
		sendbuf[i++] = 0x08;	/* 数据位*/
		sendbuf[i++] = 0x00;	/* 校验位*/
		sendbuf[i++] = 0x01;	/* 停止位*/
		break;
	case	0x010:	/* 拍摄图片并指定大小分包（10H）*/
		sendbuf[i++] = OneParam;	/* 图片大小（Resolution）*/
		sendbuf[i++] = HIBYTE(TwoParam);/*包大小（PackageSize）*/
		sendbuf[i++] = LOBYTE(TwoParam);
		sendbuf[i++] = HIBYTE(HIWORD(icurtime + 8 * 60 * 60));/* 请求拍摄图片时间（PhotoTime）*/
		sendbuf[i++] = LOBYTE(HIWORD(icurtime + 8 * 60 * 60));
		sendbuf[i++] = HIBYTE(LOWORD(icurtime + 8 * 60 * 60));
		sendbuf[i++] = LOBYTE(LOWORD(icurtime + 8 * 60 * 60));
		sendbuf[i++] = Threep;/*图像质量（ImageQuality）*/
		sendbuf[i++] = srdt.presetno;//netportparam.CurPresetno[srdt.ms_dev[portno].CameraChannel-1];/*拍照预置点（PresetNo）*/
		break;
	case	0x11:	/* 获取指定包数据（11H）*/
		sendbuf[i++] = HIBYTE(TwoParam);/*图片包号：（PackageNo）*/
		sendbuf[i++] = LOBYTE(TwoParam);
		break;
	case	0x15:	/* 读取历史图片（15H）*/
		sendbuf[i++] = HIBYTE(TwoParam);/*包大小（PackageSize）*/
		sendbuf[i++] = LOBYTE(TwoParam);
		break;
	case	0x16:	/* 通知摄像机图片读取完成或存储（16H）*/
		sendbuf[i++] = HIBYTE(HIWORD(OneParam));/*  需要保存或删除的图片拍摄时间*/
		sendbuf[i++] = LOBYTE(HIWORD(OneParam));
		sendbuf[i++] = HIBYTE(LOWORD(OneParam));
		sendbuf[i++] = LOBYTE(LOWORD(OneParam));
		sendbuf[i++] = (uint8_t)TwoParam;	/* 是否需要保存*/
		break;
	}
	sendbuf[i] = CalLpc((u_char *)&sendbuf[6], i - 6);
	i += 1;
	sendbuf[i++] = 0x16;			/* 信息尾*/
	sendbuf[3] = (uint8_t)((i - 10) >> 8);
	sendbuf[4] = (uint8_t)(i - 10);
	serialport[devparam[portno].commid].cmdlen = i;
	//return;
}

// 准备发送云台指令
int Gm_CtrlPtzCmd(u_char channel, uint32_t ptzcmd)
{
	int	i;
	char	szbuf[64];

	srdt.PtzCmdType = ptzcmd;
	// 查找装置序号
	for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
	{
		if ((channel == devparam[i].CameraChannel) && ((devparam[i].ProtocolIdx == PELCO_P_PROTOCOL)
			|| (devparam[i].ProtocolIdx == PELCO_D_PROTOCOL)))
			break;
	}
	if (i == MAX_SERIAL_DEV_NUM)
	{
		sprintf(szbuf, "没有找到摄像机使用的通道和串口通讯协议");
		DebugLog(8, szbuf, 'E');
		return 1;
	}
#if 0
	if ((2 > srdt.ms_dev[i].UseSerialidx + 1) || (MAX_SERIAL_PORT_NUM < srdt.ms_dev[i].UseSerialidx + 1))
	{
		sprintf(szbuf, "通道%d摄像机错误的使用了串口%d", channel, srdt.ms_dev[i].UseSerialidx + 1);
		LOGI("%s", szbuf);
		return 1;
	}
	else
	{
#endif
		sprintf(szbuf, "摄像机通道%d 使用串口%d", channel, devparam[i].commid + 1);
		DebugLog(devparam[i].commid, szbuf, 'I');
		//}
		srdt.usecameradevidx = i;
		// 查找串口序号
		// 1.打开串口电源
		//Gm_OpenSensorsPower();
		// 2.打开串口通讯
		//Gm_OpenSerialPort(i);

		srdt.SendStopPtzCmdTimeCnt = -1;
		//return 1;
		return Gm_Camera_Timer();
		//return 1;
	}

	// 发送转动摄像机云台命令定时器
	int Gm_Camera_Timer()
	{
		char	szbuf[128];

		if (PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx)
		{
			switch (srdt.PtzCmdType)
			{
			case P_Auto_Scan:
				srdt.PtzCmdType = D_Auto_Scan;
				break;
			case P_IRIS_CLOSE:
				srdt.PtzCmdType = D_IRIS_CLOSE;
				break;
			case P_IRIS_OPEN:
				srdt.PtzCmdType = D_IRIS_OPEN;
				break;
			case P_FOCUS_NEAR:
				srdt.PtzCmdType = D_FOCUS_NEAR;
				break;
			case P_FOCUS_FAR:
				srdt.PtzCmdType = D_FOCUS_FAR;
				break;
			case P_ZOOM_WIDE:
				srdt.PtzCmdType = D_ZOOM_WIDE;
				break;
			case P_ZOOM_TELE:
				srdt.PtzCmdType = D_ZOOM_TELE;
				break;
			case P_MOVE_DOWN:
				srdt.PtzCmdType = D_MOVE_DOWN;
				break;
			case P_MOVE_UP:
				srdt.PtzCmdType = D_MOVE_UP;
				break;
			case P_MOVE_LEFT:
				srdt.PtzCmdType = D_MOVE_LEFT;
				break;
			case P_MOVE_RIGHT:
				srdt.PtzCmdType = D_MOVE_RIGHT;
				break;
			}
		}
		if (srdt.SendStopPtzCmdTimeCnt == -1)
		{
			if (serialport[srdt.camerauseserial].cmdlen > 0)
				return -1;
			if (PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx)
				Gm_SendPelco_DCommand(srdt.PtzCmdType);
			else
				Gm_SendPelco_pCommand(srdt.PtzCmdType);

			if ((SET_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000))
				|| (MOVE_TO_PRESETNO == (srdt.PtzCmdType & 0xFFFF0000)))
			{
				//srdt.sampling &= 0xFD;
				return 1;
			}
			srdt.PtzCmdType = Cmd_Cancel;
			srdt.SendStopPtzCmdTimeCnt = 0;
		}
		return 1;
#if 0
		//if(srdt.SendStopPtzCmdTimeCnt > PTZ_MOVETIME*1000/TIMER_CNT)
		{
			if (serialport[srdt.camerauseserial].cmdlen > 0)
				return -1;
			if (PELCO_D_PROTOCOL == devparam[srdt.usecameradevidx].ProtocolIdx)
				Gm_SendPelco_DCommand(srdt.PtzCmdType);
			else
				Gm_SendPelco_pCommand(srdt.PtzCmdType);
			srdt.SendStopPtzCmdTimeCnt = -1;
			//srdt.sampling &= 0xFD;
			return 1;
		}
		//else
		 //   srdt.SendStopPtzCmdTimeCnt ++;
		//return -1;
#endif
	}

	/********************************************************************************
	*						 生成 PELCO_P 命令					      			*
	*********************************************************************************/
	void Gm_SendPelco_pCommand(uint32_t cmdtype)
	{
		int		len;
		uint8_t	commandbuf[32];
		char		buf[128];

		len = 0;
		commandbuf[len++] = (uint8_t)0xA0;
		commandbuf[len++] = (uint8_t)devparam[srdt.usecameradevidx].devaddr;
		commandbuf[len++] = (uint8_t)(cmdtype >> 24);
		commandbuf[len++] = (uint8_t)(cmdtype >> 16);
		commandbuf[len++] = (uint8_t)(cmdtype >> 8);
		commandbuf[len++] = (uint8_t)(cmdtype);
		commandbuf[len++] = (uint8_t)0xAF;
		commandbuf[len] = (uint8_t)Gm_Pelco_pXORCheck(commandbuf, len);
		len++;
		serialport[srdt.camerauseserial].cmdlen = len;
		Gm_SetSerialPortParam(srdt.camerauseserial);
		//unsigned char sendbuf[] = {0x68,0x00,0x00,0x68,0x0ff,0x02,0x01,0x16};
		//len = GM_SerialComSend(sendbuf, sizeof(sendbuf), srdt.camerauseserial);

		len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial);
		if (len < 1)
		{
			DebugLog(srdt.camerauseserial, "发送Pelco_p命令失败", 'E');
		}
		else
		{
			sprintf(buf, "发送串口%d 像机通道%d Pelco_P命令:",
				srdt.camerauseserial + 1, devparam[srdt.usecameradevidx].CameraChannel);
			BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D');
		}
		ClearCmdFormPollCmdBuf(srdt.camerauseserial);
	}

	uint8_t Gm_Pelco_pXORCheck(uint8_t *msg, int len)
	{
		int		i;
		uint8_t	checkvalue = 0;

		if (len <= 0)
			return checkvalue;
		checkvalue = msg[0];
		for (i = 1; i < len; i++)
			checkvalue ^= msg[i];
		return checkvalue;
	}

	/********************************************************************************
	*						 生成 PELCO_D 命令					      			*
	*********************************************************************************/
	void Gm_SendPelco_DCommand(uint32_t cmdtype)
	{
		int		len;
		uint8_t	commandbuf[32];
		char		buf[128];

		len = 0;
#if 1	/* Pelco_D*/
		commandbuf[len++] = (uint8_t)0xFF;
		commandbuf[len++] = (uint8_t)devparam[srdt.usecameradevidx].devaddr;
		commandbuf[len++] = (uint8_t)(cmdtype >> 24);
		commandbuf[len++] = (uint8_t)(cmdtype >> 16);
		commandbuf[len++] = (uint8_t)(cmdtype >> 8);
		commandbuf[len++] = (uint8_t)(cmdtype);
		commandbuf[len] = (uint8_t)Gm_Pelco_DCheck(commandbuf, len);
#endif
		len++;
		serialport[srdt.camerauseserial].cmdlen = len;
		Gm_SetSerialPortParam(srdt.camerauseserial);
		len = GM_SerialComSend(commandbuf, len, srdt.camerauseserial);
		if (len < 1)
		{
			DebugLog(srdt.camerauseserial, "发送Pelco_D命令失败", 'E');
		}
		else
		{
			sprintf(buf, "发送串口%d 像机通道%d Pelco_D命令:",
				srdt.camerauseserial + 1, devparam[srdt.usecameradevidx].CameraChannel);
			BytestreamLOG(srdt.camerauseserial, buf, commandbuf, len, 'D');
		}
		ClearCmdFormPollCmdBuf(srdt.camerauseserial);
		//serialport[srdt.camerauseserial].ForceWaitCnt = 10;
		//serialport[srdt.camerauseserial].ForceWaitFlag = 1;
	}

	// 计算Pelco_D校验
	uint8_t Gm_Pelco_DCheck(uint8_t *msg, int len)
	{
		int		i;
		uint8_t	checkvalue = 0;

		if (len <= 0)
			return checkvalue;
		checkvalue = 0;
		for (i = 1; i < len; i++)
			checkvalue += msg[i];
		return checkvalue;
	}

	/*********************************************************************************
						寻找并生成下一条倾角命令
	**********************************************************************************/
	int FindNextShxyProtocolCommand(int devidx)
	{
		int cmdno = 0;

		//如果命令缓冲区仍有命令，则退出本函数
		if ((devparam[devidx].commid + 1 < 1) || (devparam[devidx].commid + 1 > MAX_SERIAL_PORT_NUM))
			return -1;
		if (get_msec() - srdt.ms_dev[devidx].FirstCmdTimeCnt < 3 * 1000)
		{
			return -1;
		}
		//if(SLANT_PROTOCOL == devparam[devidx].ProtocolIdx)
		  //  return -1;
		switch (cmdno)
		{
		case 0:     /* 正常采集数据*/
			MakeShxyProtocolPollCommand(devidx, 0x09);
			srdt.curdevidx[devparam[devidx].commid] = devidx;
			return 1;
		case 1:     /* 测试读取地址*/
			MakeShxyProtocolPollCommand(devidx, 0x02);
			srdt.curdevidx[devparam[devidx].commid] = devidx;
			return 1;
		default:
			break;
		}
		return -1;
	}

	/*********************************************************************************
								生成下发命令
	**********************************************************************************/
	void MakeShxyProtocolPollCommand(int portno, uint8_t cmdidx)
	{
		int			i, length = 0;
		int         newaddr = 9, baud = 9600, stopbit = 1, parity = 0;
		//char			buf[128];
		u_char		*sendbuf;

		sendbuf = serialport[devparam[portno].commid].PollCmd;

		/* 测试变量*/
		cmdidx = cmdidx;

		i = 0;
		sendbuf[i++] = 0x00;		// 强制等待时间
		sendbuf[i++] = 0x00;		//
		sendbuf[i++] = 0x68;								// 起始字符
		sendbuf[i++] = (uint8_t)0x00;							// length
		sendbuf[i++] = (uint8_t)0x00;							// length
		sendbuf[i++] = 0x68;
		sendbuf[i++] = (uint8_t)devparam[portno].devaddr;		// 传感器地址
		sendbuf[i++] = cmdidx;								// 命令信息0x06
		switch (cmdidx)
		{
		case 1:    /* 设置传感器新地址*/
			sendbuf[i++] = newaddr;
			length = 1;
			break;
		case 2:    /* 广播读地址*/
			sendbuf[6] = 0xFF;
			break;
		case 3:     /* 设置串口参数*/
			sendbuf[i++] = (u_char)(baud >> 24);
			sendbuf[i++] = (u_char)(baud >> 16);
			sendbuf[i++] = (u_char)(baud >> 8);
			sendbuf[i++] = (u_char)baud;
			sendbuf[i++] = 8;
			sendbuf[i++] = parity;
			sendbuf[i++] = stopbit;
			length = 7;
			break;
		default:
			break;
		}
		sendbuf[i] = CalLpc((u_char *)&sendbuf[6], i - 6);
		i += 1;
		sendbuf[3] = length;
		sendbuf[4] = length;
		sendbuf[i++] = 0x16;								// 信息尾
		serialport[devparam[portno].commid].cmdlen = i;
	}

	unsigned char CalLpc(unsigned char *msg, int len)
	{
		int		i;
		u_char	retval = 0;

		for (i = 0; i < len; i++)
			retval += msg[i];
		return retval;
	}

	/***************************************************************
	*    		     		    读上海欣影传感器协议数据			    *
	***************************************************************/
	void ShxyProtocolRecvData(int devno, u_char *buf, int len)// 规约读数据处理
	{
		int  				i, ictime;
		//uint16_t				crc, check;
		//SERIAL_DEV_DEF	*pPortParam;
		SIO_PARAM_SERIAL_DEF *pPortParam;

		if ((devno < 0) || (devno > MAX_SERIAL_DEV_NUM))
		{
			return;
		}
		pPortParam = &serialport[devparam[devno].commid];

		for (i = 0; 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 (CheckShxyProtocolLpcError(pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen) == 1)
				{
					ShxyProtocolDataProcess(devno);
					pPortParam->m_iRevStatus = 0;
					pPortParam->RevCmdFlag = 1;
				}
				else
				{
					pPortParam->m_iRevStatus = 0;
				}
				pPortParam->m_iRecvLen = 0;
				break;
			case 255:// 错误接收数据
			default:
				if (buf[i] == 0x68)
				{
					pPortParam->m_iRevStatus = 1;
					pPortParam->m_iRecvLen = 1;
					pPortParam->m_au8RecvBuf[0] = buf[i];
				}
				else if (buf[i] == 0x16)
				{
					pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
					pPortParam->m_iRevStatus = 0;
					pPortParam->m_iRecvLen = 0;
				}
				else
				{
					pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
					if (pPortParam->m_iRecvLen > 200)
					{
						pPortParam->m_iRecvLen = 0;
					}
				}
				break;
			}
		}
	}

	//********************************************************************************
	//								检查检验和是否正确
	//********************************************************************************
	int CheckShxyProtocolLpcError(u_char* msg, int len)
	{
		int		bRetval = 0;
		int		iCheckLen;

		if (0x68 == msg[0])
		{
			if (msg[0] != msg[3])
				return bRetval;
			if (msg[len - 1] != 0x16)
				return bRetval;
			if (msg[1] != msg[2])
				return bRetval;
			iCheckLen = msg[1];
			if (CalLpc(&msg[4], iCheckLen + 2) != msg[len - 2])
				return bRetval;
			bRetval = 1;
		}
		return bRetval;
	}

	/*********************************************************************************
							上海欣影传感器协议数据处理
	**********************************************************************************/
	void ShxyProtocolDataProcess(int devno)
	{
		float			fvalue, fcorvalue, *fvalua, frnb/*, fwind*/;
		uint16_t		uDevAddr;
		uint8_t		cmdidx;
		int			i, j, aipnt, datanum;
		SERIAL_DEV_DEF	*pPortParam;
		SIO_PARAM_SERIAL_DEF *curserial;
		char			szbuf[64];

		pPortParam = &srdt.ms_dev[devno];
		curserial = &serialport[devparam[devno].commid];

		//取出装置地址,开始处理地址+++
		if (0x02 == curserial->m_au8RecvBuf[5])
		{
			devparam[devno].devaddr = curserial->m_au8RecvBuf[4];
			return;
		}

		cmdidx = curserial->m_au8RecvBuf[5];
		aipnt = pPortParam->SameTypeDevIdx;
		uDevAddr = curserial->m_au8RecvBuf[4];

		fvalua = &fvalue;
		memset(szbuf, 0, sizeof(szbuf));
		if (0x06 == cmdidx)
		{
			if (0x08 != curserial->m_au8RecvBuf[1])
				return;
			pPortParam->recvdatacnt++;
			if (pPortParam->recvdatacnt < 2)
				return;
			// ++++++++++++++++++++++++++++
			//g_SelfTest.SensorsFault |= (0x800<<aipnt);

			*(uint8_t*)fvalua = curserial->m_au8RecvBuf[9];
			*((uint8_t*)fvalua + 1) = curserial->m_au8RecvBuf[8];
			*((uint8_t*)fvalua + 2) = curserial->m_au8RecvBuf[7];
			*((uint8_t*)fvalua + 3) = curserial->m_au8RecvBuf[6];
			if ((fvalue < -59) || (fvalue > 59))
			{
				frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0;
				pPortParam->aiValue[0].EuValue *= (1 + frnb);
			}
			else
				pPortParam->aiValue[0].EuValue = fvalue;
			pPortParam->aiValue[0].AiState = SER_SAMPLE;
			//slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\
			//	+slantpntmsg[aipnt][0].AiParam.EuValueDelta;
		//slantpntmsg[aipnt][0].AiState = 1;
		//if ((gDisSunRain & 0x20) == 0x20)
			{
				sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f  ", devparam[devno].devaddr, fvalue);
				//DebugLog(devparam[devno].commid, szbuf, 'V');
			}
			//XslantSec[aipnt][srdt.SectimesamplingCnt[0]] = (short)slantpntmsg[aipnt][0].EuValue;
			//srdt.SectimesamplingCnt[0] += 1;

			*(uint8_t*)fvalua = curserial->m_au8RecvBuf[13];
			*((uint8_t*)fvalua + 1) = curserial->m_au8RecvBuf[12];
			*((uint8_t*)fvalua + 2) = curserial->m_au8RecvBuf[11];
			*((uint8_t*)fvalua + 3) = curserial->m_au8RecvBuf[10];
			//if ((gDisSunRain & 0x20) == 0x20)
			{
				sprintf(szbuf, "%sY =%0.3f  ", szbuf, fvalue);
				DebugLog(devparam[devno].commid, szbuf, 'V');
			}
			if ((fvalue < -59) || (fvalue > 59))
			{
				frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0;
				pPortParam->aiValue[1].EuValue *= (1 + frnb);
				//slantpntmsg[aipnt][1].EuValue *= (1+frnb);
			}
			else
				pPortParam->aiValue[1].EuValue = fvalue;
			pPortParam->aiValue[1].AiState = SER_SAMPLE;
			/*slantpntmsg[aipnt][1].EuValue = fvalue*slantpntmsg[aipnt][1].AiParam.fFactor\
				+slantpntmsg[aipnt][1].AiParam.EuValueDelta;
		slantpntmsg[aipnt][1].AiState = 1;*/
		//YslantSec[aipnt][srdt.SectimesamplingCnt[1]] = (short)slantpntmsg[aipnt][1].EuValue;
			srdt.SectimesamplingCnt[1] += 1;
		}
		datanum = curserial->m_au8RecvBuf[6];
		if ((0x08 != cmdidx) && (0x09 != cmdidx))
			return;

		for (i = 0, j = 7; (i < datanum) && (j < 6 + curserial->m_au8RecvBuf[1]); i++, j += 5)
		{
			if (0x08 == cmdidx)
				fvalue = (curserial->m_au8RecvBuf[j + 1] << 24) + (curserial->m_au8RecvBuf[j + 2] << 16)
				+ (curserial->m_au8RecvBuf[j + 3] << 8) + curserial->m_au8RecvBuf[j + 4];
			else
			{
				*(uint8_t*)fvalua = curserial->m_au8RecvBuf[j + 4];
				*((uint8_t*)fvalua + 1) = curserial->m_au8RecvBuf[j + 3];
				*((uint8_t*)fvalua + 2) = curserial->m_au8RecvBuf[j + 2];
				*((uint8_t*)fvalua + 3) = curserial->m_au8RecvBuf[j + 1];
			}
			switch (curserial->m_au8RecvBuf[j])
			{
			case	1:	/*温度*/
				if ((fvalue < -40) || (fvalue > 85))
				{
					frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0;
					pPortParam->aiValue[AirTempNo].EuValue *= (1 + frnb);
					weatherpntmsg[AirTempNo].EuValue *= (1 + frnb);
					//weatherpntmsg[AirTempNo].AiState = SER_SAMPLE;
				}
				else
				{
					pPortParam->aiValue[AirTempNo].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor + pPortParam->aiValue[0].AiParam.EuValueDelta;*/
					weatherpntmsg[AirTempNo].EuValue = fvalue;/*weatherpntmsg[AirTempNo].AiParam.fFactor + weatherpntmsg[AirTempNo].AiParam.EuValueDelta;*/
				}
				pPortParam->aiValue[AirTempNo].AiState = SER_SAMPLE;
				weatherpntmsg[AirTempNo].AiState = SER_SAMPLE;
				//g_SelfTest.SensorsFault |= (0x01);
				//if ((gDisSunRain & 0x80) == 0x80)
				{
					sprintf(szbuf, "ID:%d 温度:%0.3f  ", devparam[devno].devaddr, fvalue);
					//DebugLog(devparam[devno].commid, szbuf, 'V');
				}
				break;
			case	2:	/*气压*/
				if ((fvalue < 550) || (fvalue > 1060))
				{
					frnb = (GeneratingRandomNumber() % 41 - 20) / 10000.0;
					pPortParam->aiValue[AtmosNo].EuValue *= (1 + frnb);
					weatherpntmsg[AtmosNo].EuValue *= (1 + frnb);
				}
				else
				{
					pPortParam->aiValue[AtmosNo].EuValue = fvalue;/*pPortParam->aiValue[5].AiParam.fFactor + pPortParam->aiValue[5].AiParam.EuValueDelta;*/
					weatherpntmsg[AtmosNo].EuValue = fvalue;/*weatherpntmsg[AtmosNo].AiParam.fFactor + weatherpntmsg[AtmosNo].AiParam.EuValueDelta;*/
				}
				pPortParam->aiValue[AtmosNo].AiState = SER_SAMPLE;
				weatherpntmsg[AtmosNo].AiState = SER_SAMPLE;
				//g_SelfTest.SensorsFault |= (0x10);
				//if ((gDisSunRain & 0x80) == 0x80)
				{
					sprintf(szbuf, "气压:%0.3f  ", fvalue);
					DebugLog(devparam[devno].commid, szbuf, 'V');
				}
				break;
			case	3:	/*湿度*/
				if ((fvalue < 0) || (fvalue > 100))
				{
					frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0;
					pPortParam->aiValue[HumidityNo].EuValue *= (1 + frnb);
					weatherpntmsg[HumidityNo].EuValue *= (1 + frnb);
				}
				else
				{
					pPortParam->aiValue[HumidityNo].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor + pPortParam->aiValue[1].AiParam.EuValueDelta;*/
					weatherpntmsg[HumidityNo].EuValue = fvalue;/*weatherpntmsg[HumidityNo].AiParam.fFactor + weatherpntmsg[HumidityNo].AiParam.EuValueDelta;*/
				}
				pPortParam->aiValue[HumidityNo].AiState = SER_SAMPLE;
				weatherpntmsg[HumidityNo].AiState = SER_SAMPLE;
				//g_SelfTest.SensorsFault |= (0x02);
				//if ((gDisSunRain & 0x80) == 0x80)
				{
					sprintf(szbuf, "%s湿度:%0.3f  ", szbuf, fvalue);
					DebugLog(devparam[devno].commid, szbuf, 'V');
				}
				break;
			case	4:	/*雨量*/
				break;
			case	5:	/*日照*/
				break;
			case	6:	/*风速*/
				if ((fvalue < 0) || (fvalue > 80))
				{
					frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0;
					pPortParam->aiValue[WindSpeedNo].EuValue *= (1 + frnb);
					weatherpntmsg[WindSpeedNo].EuValue *= (1 + frnb);
				}
				else
				{
					pPortParam->aiValue[WindSpeedNo].EuValue = fvalue;/*pPortParam->aiValue[2].AiParam.fFactor + pPortParam->aiValue[2].AiParam.EuValueDelta;*/
					weatherpntmsg[WindSpeedNo].EuValue = fvalue;/*weatherpntmsg[WindSpeedNo].AiParam.fFactor + weatherpntmsg[WindSpeedNo].AiParam.EuValueDelta;*/
				}
				pPortParam->aiValue[WindSpeedNo].AiState = SER_SAMPLE;
				weatherpntmsg[WindSpeedNo].AiState = SER_SAMPLE;
				//g_SelfTest.SensorsFault |= (0x04);
				//if ((gDisSunRain & 0x10) == 0x10)
				{
					//fwind = fvalue/1000*0.95;
					//if(fvalue/1000 > 25)
					//	fwind -= 1.2;
					//sprintf(szbuf, "风速:%0.3f  ", fwind);
					sprintf(szbuf, "ID:%d 风速:%0.3f  ", devparam[devno].devaddr, fvalue);
				}
				break;
			case	7:	/*风向*/
				if ((fvalue / 1000 < 0) || (fvalue / 1000 > 359.99))
				{
					frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0;
					pPortParam->aiValue[WindDirectionNo].EuValue *= (1 + frnb);
					weatherpntmsg[WindDirectionNo].EuValue *= (1 + frnb);
				}
				else
				{
					pPortParam->aiValue[WindDirectionNo].EuValue = fvalue;/*pPortParam->aiValue[3].AiParam.fFactor + pPortParam->aiValue[3].AiParam.EuValueDelta;*/
					weatherpntmsg[WindDirectionNo].EuValue = fvalue;/*weatherpntmsg[WindDirectionNo].AiParam.fFactor + weatherpntmsg[WindDirectionNo].AiParam.EuValueDelta;*/
				}
				pPortParam->aiValue[WindDirectionNo].AiState = SER_SAMPLE;
				weatherpntmsg[WindDirectionNo].AiState = SER_SAMPLE;
				//g_SelfTest.SensorsFault |= (0x08);
				//if ((gDisSunRain & 0x10) == 0x10)
				{
					sprintf(szbuf, "%s 风向:%0.3f  ", szbuf, fvalue);
					DebugLog(devparam[devno].commid, szbuf, 'V');
				}
				break;
			case	8:	/*拉力*/
				pPortParam->recvdatacnt++;
				if (pPortParam->recvdatacnt < 2)
					break;

				pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\
							+pPortParam->aiValue[0].AiParam.EuValueDelta;*/
							//rallypntmsg[aipnt][0].EuValue = fvalue*rallypntmsg[aipnt][0].AiParam.fFactor\
							//			+rallypntmsg[aipnt][0].AiParam.EuValueDelta;
				pPortParam->aiValue[0].AiState = SER_SAMPLE;
				//rallypntmsg[aipnt][0].AiState = 1;
				sprintf(szbuf, "地址%d拉力:%0.3fKg  ", devparam[devno].devaddr, fvalue);
				DebugLog(devparam[devno].commid, szbuf, 'V');
				//}
				break;
			case	9:	/*倾角传感器X轴倾角*/
				if ((fvalue < -59) || (fvalue > 59))
				{
					frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0;
					pPortParam->aiValue[0].EuValue *= (1 + frnb);
					//slantpntmsg[aipnt][0].EuValue *= (1+frnb);
				}
				else
				{
					pPortParam->aiValue[0].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor\
					+pPortParam->aiValue[0].AiParam.EuValueDelta;*/
					//slantpntmsg[aipnt][0].EuValue = fvalue*slantpntmsg[aipnt][0].AiParam.fFactor\
                    //+slantpntmsg[aipnt][0].AiParam.EuValueDelta;
				}
				pPortParam->aiValue[0].AiState = SER_SAMPLE;
				//slantpntmsg[aipnt][0].AiState = 1;
				sprintf(szbuf, "倾角ID:%d slantangle X=%0.3f  ", devparam[devno].devaddr, fvalue);
				break;
			case	10:	/*倾角传感器Y轴倾角*/
				sprintf(szbuf, "%s Y =%0.3f  ", szbuf, fvalue);
				DebugLog(devparam[devno].commid, szbuf, 'V');

				if ((fvalue < -59) || (fvalue > 59))
				{
					frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0;
					pPortParam->aiValue[1].EuValue *= (1 + frnb);
				}
				else
				{
					pPortParam->aiValue[1].EuValue = fvalue;/*pPortParam->aiValue[1].AiParam.fFactor\
					+pPortParam->aiValue[1].AiParam.EuValueDelta;*/
				}
				pPortParam->aiValue[1].AiState = SER_SAMPLE;
				//slantpntmsg[aipnt][1].AiState = 1;
				break;

			}
		}
	}

	void delete_old_files(const char *path, int days)
	{
		struct stat file_stat;
		struct tm *file_tm;
		time_t now = time(NULL);
		DIR *dir = opendir(path);
		struct dirent *entry;
		char szbuf[1024];
		char fullpath[256];

		memset(szbuf, 0, sizeof(szbuf));
		if (!dir)
		{
			sprintf(szbuf, "delete_old_files opendir %s error ", path);
			DebugLog(8, szbuf, 'E');
			return;
		}

		while ((entry = readdir(dir)))
		{
			memset(szbuf, 0, sizeof(szbuf));
			if (entry->d_type == DT_REG)
			{ // 只处理普通文件
				snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);

				if (stat(fullpath, &file_stat) == -1)
				{
					perror("stat");
					sprintf(szbuf, "stat");
					DebugLog(8, szbuf, 'E');
					continue;
				}

				localtime_r(&(file_stat.st_mtime), file_tm);
				//file_tm = localtime(&(file_stat.st_mtime));

				if (difftime(now, mktime(file_tm)) > days * 24 * 60 * 60)
				{
					if (unlink(fullpath) == -1)
					{ // 删除文件
						perror("unlink");
					}
				}
			}
		}

		closedir(dir);
	}
	/*********************************************************************************
				把16进制和10进制ASCII字符串转换成int整数
	*********************************************************************************/
	int ATOI(char *buf)
	{
		int	i, ilen, iRetVal;

		if (NULL == buf)
			return 0;
		ilen = strlen(buf);
		if (ilen > 2)
		{
			if ((buf[0] == '0') && ((buf[1] == 'x') || (buf[1] == 'X')))
			{
				iRetVal = 0;
				for (i = 2; i < ilen; i++)
				{
					iRetVal = (iRetVal << 4) + HexCharToInt(buf[i]);
				}
			}
			else
			{
				iRetVal = atoi(buf);
			}
		}
		else
		{
			iRetVal = atoi(buf);
		}
		return iRetVal;
	}

#if 0
	// 控制关闭传感器电源
	void Gm_CtrlCloseSensorsPower(int devidx)
	{
		if ((devidx < 0) || (devidx > MAX_SERIAL_DEV_NUM - 1))
			return;
		srdt.ms_dev[devidx].uOpenPowerFlag = CLOSEPOWER;
	}


	// 检查传感器电源是否应该关闭或打开
	void Gm_CheckSensorsPower(void)
	{
		int	i, j;

		for (i = 0; i < MAX_SERIAL_DEV_NUM - 2; i++)
		{
			if ((1 > srdt.ms_dev[i].ProtocolIdx) || (INVALID_PROTOCOL <= srdt.ms_dev[i].ProtocolIdx))
				continue;
			if ((PELCO_P_PROTOCOL == srdt.ms_dev[i].ProtocolIdx) || (PELCO_D_PROTOCOL == srdt.ms_dev[i].ProtocolIdx)
				|| (SERIALCAMERA_PROTOCOL == srdt.ms_dev[i].ProtocolIdx))
				continue;
			// 需要传感器处于上电状态
			for (j = 0; j < MAX_SERIAL_DEV_NUM - 2; j++)
			{
				if ((srdt.ms_dev[i].PowerPort == srdt.ms_dev[j].PowerPort) && (srdt.ms_dev[j].uOpenPowerFlag == OPENPOWER))
					break;
			}
			if (j < MAX_SERIAL_DEV_NUM - 2)
				continue;

		}
	}
#endif

	int GeneratingRandomNumber(void)
	{
		int	ictime, randomdate;
		/* 生成随机数n-m -> rand()%(m-n+1)+n*/
		ictime = (int)time(NULL);
		srand((uint32_t)ictime);
		randomdate = rand();
		return randomdate;
	}

	/* 串口启动接口函数 开始*/
	void Collect_sensor_data()
	{
#if 0
		int     i;

		for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
		{
			devparam[i].IsNoInsta = sensorParam[i].IsNoInsta;
			if (0 == sensorParam[i].IsNoInsta)
				continue;
			devparam[i].ProtocolIdx = sensorParam[i].SensorsType;
			devparam[i].devaddr = sensorParam[i].devaddr;
			devparam[i].baudrate = getBaudrate(sensorParam[i].baudrate);
			memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
			memmove(devparam[i].pathname, sensorParam[i].pathname, sizeof(devparam[i].pathname));
			devparam[i].databit = sensorParam[i].databit;
			devparam[i].stopbit = (int)(sensorParam[i].stopbit * 10);
			devparam[i].CameraChannel = sensorParam[i].CameraChannel;
			devparam[i].Phase = sensorParam[i].Phase;
		}
#endif
#if 1
		static int ideletefile = 0;
		time_t          now;
		struct tm       t0;
		const char *path = "/sdcard/log"; // 指定目录路径
		int days = 15; // 删除15天前的log文件

		now = time(NULL);
		localtime_r(&now, &t0);
		if ((0 == t0.tm_hour) && (0 == ideletefile))
		{
			delete_old_files(path, days);
			ideletefile++;
		}
		if (0 < t0.tm_hour)
			ideletefile = 0;
#endif
		GM_StartSerialComm();
	}

	void CameraPhotoCmd(int phototime, u_char channel, int cmdidx, u_char bImageSize, u_char presetno)
	{
#if 0
		int     i;
		//speed_t  baudrate;

		for (i = 0; i < MAX_SERIAL_DEV_NUM; i++)
		{
			devparam[i].IsNoInsta = sensorParam[i].IsNoInsta;
			if (0 == sensorParam[i].IsNoInsta)
				continue;
			devparam[i].ProtocolIdx = sensorParam[i].SensorsType;
			devparam[i].devaddr = sensorParam[i].devaddr;
			//baudrate = getBaudrate(sensorParam[i].baudrate);
			devparam[i].baudrate = getBaudrate(sensorParam[i].baudrate);
			devparam[i].databit = sensorParam[i].databit;
			devparam[i].stopbit = (int)(sensorParam[i].stopbit * 10);
			devparam[i].CameraChannel = sensorParam[i].CameraChannel;
			devparam[i].Phase = sensorParam[i].Phase;
			memset(devparam[i].pathname, 0, sizeof(devparam[i].pathname));
			memmove(devparam[i].pathname, sensorParam[i].pathname, sizeof(devparam[i].pathname));
		}

		FindDevUseSerialCommNo();
		for (;;)
		{
			Gm_CtrlPtzCmd(1, P_MOVE_LEFT);
			sleep(3);
			GM_AllSerialComRecv();
			Gm_CtrlPtzCmd(1, Cmd_Cancel);
			sleep(10);
		}
#endif
		srdt.bImageSize = bImageSize;
		srdt.presetno = presetno;
		srdt.sendphototime = phototime;
		GM_StartSerialCameraPhoto(1, cmdidx);
	}
	/* 串口启动接口函数 结束*/

	/* 数据和图片采集数据返回函数 开始*/
	int GetWeatherData(Data_DEF *data, int datano)
	{
		int     i;

		if (NULL == data)
			return -1;
		if ((AirTempNo > datano) || (datano > OpticalRadiationNo))
			return -1;
		data->EuValue = weatherpntmsg[datano].EuValue;
		data->AiState = weatherpntmsg[datano].AiState;
		if ((SER_SAMPLEFAIL == data->AiState) || (SAMPLINGSUCCESS == data->AiState))
		{
			weatherpntmsg[datano].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetAirTempData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[AirTempNo].EuValue;
		airt->AiState = weatherpntmsg[AirTempNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[AirTempNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetHumidityData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[HumidityNo].EuValue;
		airt->AiState = weatherpntmsg[HumidityNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[HumidityNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetWindSpeedData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[WindSpeedNo].EuValue;
		airt->AiState = weatherpntmsg[WindSpeedNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[WindSpeedNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetWindDirectionData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[WindDirectionNo].EuValue;
		airt->AiState = weatherpntmsg[WindDirectionNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[WindDirectionNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetRainfallData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[RainfallNo].EuValue;
		airt->AiState = weatherpntmsg[RainfallNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[RainfallNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetAtmosData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[AtmosNo].EuValue;
		airt->AiState = weatherpntmsg[AtmosNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[AtmosNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetOpticalRadiationData(Data_DEF *airt)
	{
		if (NULL == airt)
			return -1;
		airt->EuValue = weatherpntmsg[OpticalRadiationNo].EuValue;
		airt->AiState = weatherpntmsg[OpticalRadiationNo].AiState;
		if ((SER_SAMPLEFAIL == airt->AiState) || (SAMPLINGSUCCESS == airt->AiState))
		{
			weatherpntmsg[OpticalRadiationNo].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetPullValue(int devno, Data_DEF *data)
	{
		if (NULL == data)
			return -1;
		if ((0 > devno) || (MAX_SERIAL_DEV_NUM < devno))
			return -1;
		if (RALLY_PROTOCOL != devparam[devno].ProtocolIdx)
			return -1;
		data->EuValue = srdt.ms_dev[devno].aiValue[0].EuValue;
		data->AiState = srdt.ms_dev[devno].aiValue[0].AiState;
		if ((SER_SAMPLEFAIL == data->AiState) || (SAMPLINGSUCCESS == data->AiState))
		{
			srdt.ms_dev[devno].aiValue[0].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetAngleValue(int devno, Data_DEF *data, int Xy)
	{
		if (NULL == data)
			return -1;
		if ((0 > devno) || (MAX_SERIAL_DEV_NUM < devno))
			return -1;
		if (SLANT_PROTOCOL != devparam[devno].ProtocolIdx)
			return -1;
		if ((0 > Xy) || (1 < Xy))
			return -1;

		data->EuValue = srdt.ms_dev[devno].aiValue[Xy].EuValue;
		data->AiState = srdt.ms_dev[devno].aiValue[Xy].AiState;
		if ((SER_SAMPLEFAIL == data->AiState) || (SAMPLINGSUCCESS == data->AiState))
		{
			srdt.ms_dev[devno].aiValue[Xy].AiState = SER_IDLE;
			return 2;
		}
		return 1;
	}

	int GetImage(int devno, IMAGE_DEF *photo)
	{
		if (NULL == photo)
			return -1;
		if ((0 > devno) || (MAX_SERIAL_DEV_NUM < devno))
			return -1;
		if ((PELCO_D_PROTOCOL != devparam[devno].ProtocolIdx) && (PELCO_P_PROTOCOL != devparam[devno].ProtocolIdx) && (SERIALCAMERA_PROTOCOL != devparam[devno].ProtocolIdx))
			return -1;
		photo->presetno = srdt.ms_dev[devno].image.presetno;
		photo->phototime = srdt.ms_dev[devno].image.phototime;
		memset(photo->photoname, 0, sizeof(photo->photoname));
		memmove(photo->photoname, srdt.ms_dev[devno].image.photoname, sizeof(photo->photoname));
		photo->imagelen = srdt.ms_dev[devno].image.imagelen;
		photo->state = srdt.ms_dev[devno].image.state;
		if ((SER_SAMPLEFAIL == photo->state) || (SAMPLINGSUCCESS == photo->state))
		{
			srdt.ms_dev[devno].image.state = SER_IDLE;
			return 2;
		}
		return 1;
	}
	/* 数据和图片采集数据返回函数 结束*/