|
|
|
@ -23,13 +23,14 @@
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
|
|
#include <AndroidHelper.h>
|
|
|
|
|
#include "AndroidHelper.h"
|
|
|
|
|
#include "SensorsProtocol.h"
|
|
|
|
|
//#include "Eint.h"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁
|
|
|
|
|
pthread_mutex_t camera_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁
|
|
|
|
|
pthread_mutex_t bd_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁
|
|
|
|
|
|
|
|
|
|
SIO_PARAM_SERIAL_DEF serialport[MAX_SERIAL_PORT_NUM];
|
|
|
|
|
|
|
|
|
@ -924,6 +925,7 @@ void Gm_FindAllSensorsCommand()
|
|
|
|
|
case PELCO_P_PROTOCOL: /* 摄像机协议*/
|
|
|
|
|
case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (flag == -1)
|
|
|
|
@ -1485,7 +1487,7 @@ void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial)
|
|
|
|
|
case 1: // 自检
|
|
|
|
|
if (0 == curserial->ptz_state.ptz_status)
|
|
|
|
|
sprintf(szbuf, "云台自检结束!");
|
|
|
|
|
else if (1 == curserial->ptz_state.ptz_status)
|
|
|
|
|
else if (0 < curserial->ptz_state.ptz_status)
|
|
|
|
|
sprintf(szbuf, "云台正在自检!");
|
|
|
|
|
else
|
|
|
|
|
sprintf(szbuf, "云台自检发生错误!");
|
|
|
|
@ -1494,9 +1496,9 @@ void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial)
|
|
|
|
|
case 2: // 调用预置点
|
|
|
|
|
if (0 == curserial->ptz_state.ptz_status)
|
|
|
|
|
sprintf(szbuf, "调用预置位结束,云台处于所调预置位!");
|
|
|
|
|
else if (1 == curserial->ptz_state.ptz_status)
|
|
|
|
|
else if (0 < curserial->ptz_state.ptz_status)
|
|
|
|
|
sprintf(szbuf, "调用预置位,云台正在前往所调预置位位置!");
|
|
|
|
|
else if (2 == curserial->ptz_state.ptz_status)
|
|
|
|
|
else if (2 == (curserial->ptz_state.ptz_status & 0x0f))
|
|
|
|
|
sprintf(szbuf, "调用预置位时,机芯电源未打开!");
|
|
|
|
|
else
|
|
|
|
|
sprintf(szbuf, "调用预置位时,发生了错误,未正确执行!");
|
|
|
|
@ -1505,7 +1507,7 @@ void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial)
|
|
|
|
|
case 3: // 一般状态
|
|
|
|
|
if (0 == curserial->ptz_state.ptz_status)
|
|
|
|
|
sprintf(szbuf, "云台处于静止状态!");
|
|
|
|
|
else if (1 == curserial->ptz_state.ptz_status)
|
|
|
|
|
else if (0 < curserial->ptz_state.ptz_status)
|
|
|
|
|
sprintf(szbuf, "云台正在运动!");
|
|
|
|
|
else
|
|
|
|
|
sprintf(szbuf, "云台发生错误!");
|
|
|
|
@ -2415,13 +2417,23 @@ void MakeShxyProtocolPollCommand(int portno, uint8_t cmdidx)
|
|
|
|
|
unsigned char CalLpc(unsigned char *msg, int len)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
u_char retval = 0;
|
|
|
|
|
unsigned char retval = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
|
retval += msg[i];
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char BDXorCheck(unsigned char *msg, int len)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
unsigned char retval = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
|
retval ^= msg[i];
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***************************************************************
|
|
|
|
|
* 读上海欣影传感器协议数据 *
|
|
|
|
|
***************************************************************/
|
|
|
|
@ -3264,14 +3276,17 @@ void GM_CameraSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam)
|
|
|
|
|
recvlen = read(pPortParam->fd, &recvbuf[i], sizeof(recvbuf)-i);/* 在串口读取字符串 */
|
|
|
|
|
t1 = get_msec();
|
|
|
|
|
if(t1-t0 >= 350)
|
|
|
|
|
break;
|
|
|
|
|
{
|
|
|
|
|
i += recvlen;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recvlen = i;
|
|
|
|
|
if (recvlen < 1)
|
|
|
|
|
return;
|
|
|
|
|
#if 1
|
|
|
|
|
sprintf(buf, "收到Camera, %d字节数据:", recvlen);
|
|
|
|
|
sprintf(buf, "收到BD, %d字节数据:", recvlen);
|
|
|
|
|
BytestreamLOG(0, buf, recvbuf, recvlen, 'I');
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -3463,6 +3478,465 @@ int QueryPtzState(PTZ_STATE *ptz_state, int cmdidx, const char *serfile, unsign
|
|
|
|
|
pthread_mutex_unlock(&camera_mutex); // 解锁
|
|
|
|
|
return flag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Query_BDGNSS_Data(BD_GNSS_DATA *BD_data, int samptime, const char *serfile, unsigned int baud)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&bd_mutex);
|
|
|
|
|
int flag = 0;
|
|
|
|
|
char szbuf[128], logbuf[128];
|
|
|
|
|
SIO_PARAM_SERIAL_DEF *cameraport=NULL;
|
|
|
|
|
|
|
|
|
|
if(NULL == BD_data)
|
|
|
|
|
return -1;
|
|
|
|
|
if(samptime < 5)
|
|
|
|
|
samptime = 5;
|
|
|
|
|
cameraport = (SIO_PARAM_SERIAL_DEF*)malloc(sizeof(SIO_PARAM_SERIAL_DEF));
|
|
|
|
|
|
|
|
|
|
cameraport->Retry = 0;
|
|
|
|
|
cameraport->RetryTime = 1000;
|
|
|
|
|
cameraport->WaitTime = 0;
|
|
|
|
|
cameraport->m_iRevStatus = 0;
|
|
|
|
|
cameraport->m_iRecvLen = 0;
|
|
|
|
|
cameraport->m_iNeedRevLength = 0;
|
|
|
|
|
cameraport->fd = -1;
|
|
|
|
|
memset(cameraport->m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区
|
|
|
|
|
ClearCameraCmdFormPollCmdBuf(cameraport);
|
|
|
|
|
|
|
|
|
|
flag = Gm_OpenCameraSerial(cameraport, serfile, baud);
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
memset(szbuf, 0, sizeof(szbuf));
|
|
|
|
|
srdt.iLastGetPhotoNo = -1;
|
|
|
|
|
cameraport->SerialCmdidx = -1;
|
|
|
|
|
cameraport->FirstCmdTimeCnt = get_msec();
|
|
|
|
|
#endif
|
|
|
|
|
if(-1 == flag)
|
|
|
|
|
{
|
|
|
|
|
if(NULL != cameraport)
|
|
|
|
|
{
|
|
|
|
|
free(cameraport);
|
|
|
|
|
cameraport = NULL;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0x00 == flag)
|
|
|
|
|
{
|
|
|
|
|
sprintf(szbuf, "北斗定位数据查询启动串口定时器!");
|
|
|
|
|
DebugLog(8, szbuf, 'I');
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
usleep(10);
|
|
|
|
|
//LOGW("polltime=%ldms", get_msec()-polltime);
|
|
|
|
|
//polltime = get_msec();
|
|
|
|
|
flag = GM_BdSerialTimer(cameraport);
|
|
|
|
|
if(get_msec() - cameraport->FirstCmdTimeCnt > samptime*1000)
|
|
|
|
|
{
|
|
|
|
|
DebugLog(8, "退出查询北斗定位数据流程!", 'V');
|
|
|
|
|
memmove((void*)BD_data, &cameraport->bd_data, sizeof(BD_GNSS_DATA));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(NULL != cameraport)
|
|
|
|
|
{
|
|
|
|
|
free(cameraport);
|
|
|
|
|
cameraport = NULL;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&bd_mutex); // 解锁
|
|
|
|
|
return flag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GM_BdSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam)
|
|
|
|
|
{
|
|
|
|
|
int flag = 0;
|
|
|
|
|
|
|
|
|
|
GM_BdSerialComRecv(pPortParam);
|
|
|
|
|
return flag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GM_BdSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam)
|
|
|
|
|
{
|
|
|
|
|
int i, recvlen;
|
|
|
|
|
u_char recvbuf[RECVDATA_MAXLENTH];
|
|
|
|
|
char buf[RECVDATA_MAXLENTH+256];
|
|
|
|
|
int64_t t0, t1;
|
|
|
|
|
|
|
|
|
|
t0 = get_msec();
|
|
|
|
|
|
|
|
|
|
memset(recvbuf, 0, sizeof(recvbuf));
|
|
|
|
|
if (pPortParam->fd <= 0)
|
|
|
|
|
return;
|
|
|
|
|
i=0;
|
|
|
|
|
recvlen = 0;
|
|
|
|
|
memset(recvbuf, 0, sizeof(recvbuf));
|
|
|
|
|
for(;;)
|
|
|
|
|
{
|
|
|
|
|
i += recvlen;
|
|
|
|
|
recvlen = read(pPortParam->fd, &recvbuf[i], sizeof(recvbuf)-i);/* 在串口读取字符串 */
|
|
|
|
|
t1 = get_msec();
|
|
|
|
|
if(t1-t0 >= 350)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recvlen = i;
|
|
|
|
|
if (recvlen < 1)
|
|
|
|
|
return;
|
|
|
|
|
#if 1
|
|
|
|
|
sprintf(buf, "收到BD, %d字节数据:%s", recvlen, recvbuf);
|
|
|
|
|
DebugLog(0, (char*)recvbuf, 'I');
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
BdRecvData(pPortParam, recvbuf, recvlen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BdRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
unsigned char bdxor=0, srcxor=0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
switch (pPortParam->m_iRevStatus)
|
|
|
|
|
{
|
|
|
|
|
case 0: // 搜索起始符 '$'
|
|
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
|
|
memset(pPortParam->m_au8RecvBuf, 0,sizeof(pPortParam->m_au8RecvBuf));
|
|
|
|
|
if ('$' == buf[i])
|
|
|
|
|
{
|
|
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
|
|
pPortParam->m_iRevStatus = 1; // 进入数据接收状态
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 1: // 接收数据直到 '*'
|
|
|
|
|
if (pPortParam->m_iRecvLen >= RECVDATA_MAXLENTH)
|
|
|
|
|
{
|
|
|
|
|
// 缓冲区溢出,重置状态
|
|
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
|
|
|
|
|
|
|
if (buf[i] == '*')
|
|
|
|
|
{
|
|
|
|
|
pPortParam->m_iRevStatus = 2; // 进入校验码接收状态
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 2: // 接收校验码(2字节十六进制)和<CR><LF>
|
|
|
|
|
if (pPortParam->m_iRecvLen >= RECVDATA_MAXLENTH)
|
|
|
|
|
{
|
|
|
|
|
// 缓冲区溢出,重置状态
|
|
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
|
|
|
|
|
|
|
// 检测到换行符(0x0A),检查前一个字符是否为回车符(0x0D)
|
|
|
|
|
if (buf[i] == 0x0A)
|
|
|
|
|
{
|
|
|
|
|
if (pPortParam->m_iRecvLen >= 5 &&
|
|
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] == 0x0D)
|
|
|
|
|
{
|
|
|
|
|
// 提取校验码(*后的两个字符)
|
|
|
|
|
char hex_str[3] = {
|
|
|
|
|
(char)pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 4],
|
|
|
|
|
(char)pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 3],
|
|
|
|
|
'\0'
|
|
|
|
|
};
|
|
|
|
|
srcxor = (uint8_t)strtol(hex_str, NULL, 16);
|
|
|
|
|
|
|
|
|
|
// 计算校验值(从$后的第一个字符到*前的字符)
|
|
|
|
|
uint8_t calc_xor = BDXorCheck(&pPortParam->m_au8RecvBuf[1],pPortParam->m_iRecvLen - 6);// 长度 = 总长度 - ($ + *HH + \r\n)
|
|
|
|
|
|
|
|
|
|
if (srcxor == calc_xor)
|
|
|
|
|
{
|
|
|
|
|
BD_NMEA0183_PortDataProcess(pPortParam);
|
|
|
|
|
pPortParam->RevCmdFlag = 1;
|
|
|
|
|
}
|
|
|
|
|
// 重置状态,准备接收下一帧
|
|
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 格式错误,丢弃数据
|
|
|
|
|
pPortParam->m_iRevStatus = 0;
|
|
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 255:// 错误接收数据
|
|
|
|
|
default:
|
|
|
|
|
if (buf[i] == '$')
|
|
|
|
|
{
|
|
|
|
|
pPortParam->m_iRevStatus = 1;
|
|
|
|
|
pPortParam->m_iRecvLen = 1;
|
|
|
|
|
pPortParam->m_au8RecvBuf[0] = buf[i];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
|
|
|
|
|
if (pPortParam->m_iRecvLen > 200)
|
|
|
|
|
{
|
|
|
|
|
pPortParam->m_iRecvLen = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
$BDRMC,023656.00,A,2240.61563,N,11359.86512,E,0.16,,140324,,,A,V*2C
|
|
|
|
|
$BDVTG,,,,,0.16,N,0.30,K,A*2F
|
|
|
|
|
$BDGGA,023656.00,2240.61563,N,11359.86512,E,1,23,0.7,96.53,M,-3.52,M,,*5B
|
|
|
|
|
$BDGSA,A,3,01,02,03,04,05,06,07,09,10,16,19,20,1.0,0.7,0.8,4*30
|
|
|
|
|
$BDGSV,6,1,23,01,45,125,38,02,46,235,40,03,61,189,46,04,32,112,37,1*7B
|
|
|
|
|
$BDGLL,2240.61563,N,11359.86512,E,023656.00,A,A*78
|
|
|
|
|
$BDZDA,023656.00,14,03,2024,00,00*71
|
|
|
|
|
$GPTXT,01,01,01,ANTENNA OPEN*25
|
|
|
|
|
GLL:经度、纬度、UTC 时间
|
|
|
|
|
GSA:北斗接收机操作模式,定位使用的卫星,DOP 值
|
|
|
|
|
GSV:可见北斗卫星信息、仰角、方位角、信噪比(SNR)
|
|
|
|
|
RMC:时间、日期、位置、速度
|
|
|
|
|
VTG:地面速度信息
|
|
|
|
|
ZDA: 时间、日期
|
|
|
|
|
TXT:用于天线状态检测
|
|
|
|
|
*/
|
|
|
|
|
void BD_NMEA0183_PortDataProcess(SIO_PARAM_SERIAL_DEF *curserial)
|
|
|
|
|
{
|
|
|
|
|
BD_NMEA0183_PROC_FUNC bd_nmea0183_call[] = {
|
|
|
|
|
{"$BDRMC",BD_get_BDRMC_data},/* 时间、日期、位置、速度*/
|
|
|
|
|
{"$BDVTG",NULL},/* 地面速度信息*/
|
|
|
|
|
{"$BDGGA",NULL},/* 时间、位置、定位类型*/
|
|
|
|
|
{"$BDGSA",NULL},/* 北斗接收机操作模式,定位使用的卫星,DOP 值 */
|
|
|
|
|
{"$BDGSV",NULL},/* 可见北斗卫星信息、仰角、方位角、信噪比(SNR)*/
|
|
|
|
|
{"$BDGLL",NULL},/* 经度、纬度、UTC 时间*/
|
|
|
|
|
{"$BDZDA",NULL},/* 时间、日期 */
|
|
|
|
|
{"$GPTXT",NULL},/* 用于天线状态检测*/
|
|
|
|
|
};/* irows*/
|
|
|
|
|
int i=0, irows;
|
|
|
|
|
char szbuf[512];
|
|
|
|
|
//char *cmd=NULL, *sourestr=NULL;
|
|
|
|
|
//RTUMSG rtumsg;
|
|
|
|
|
|
|
|
|
|
if(NULL == curserial)
|
|
|
|
|
return;
|
|
|
|
|
irows = sizeof(bd_nmea0183_call)/sizeof(BD_NMEA0183_PROC_FUNC);
|
|
|
|
|
memset(szbuf, 0, sizeof(szbuf));
|
|
|
|
|
//sprintf(szbuf, "rows = %d", irows);
|
|
|
|
|
DebugLog(0, (char*)curserial->m_au8RecvBuf, 'I');
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData));
|
|
|
|
|
memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen);
|
|
|
|
|
rtumsg.MsgLen = curserial->m_iRecvLen;
|
|
|
|
|
/* 析出关键字符串*/
|
|
|
|
|
cmd = (char *)rtumsg.MsgData;
|
|
|
|
|
sourestr = strstr((char *)rtumsg.MsgData, ",");
|
|
|
|
|
*sourestr = 0;
|
|
|
|
|
sprintf(szbuf, "cmd_len = %d, cmd:%s", strlen(cmd), cmd);
|
|
|
|
|
DebugLog(0, szbuf, 'I');
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
for(i=0; i<irows; i++)
|
|
|
|
|
{
|
|
|
|
|
if(strstr((char *)curserial->m_au8RecvBuf, bd_nmea0183_call[i].cmd_name))
|
|
|
|
|
{
|
|
|
|
|
sprintf(szbuf, "cmd_name[%d]:%s", i, bd_nmea0183_call[i].cmd_name);
|
|
|
|
|
DebugLog(0, szbuf, 'I');
|
|
|
|
|
if(NULL != bd_nmea0183_call[i].recv_process)
|
|
|
|
|
bd_nmea0183_call[i].recv_process(curserial);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(i >= irows)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BD_get_BDRMC_data(SIO_PARAM_SERIAL_DEF *curserial)
|
|
|
|
|
{
|
|
|
|
|
const int UTC_TIME = 1;
|
|
|
|
|
const int STATUS = 2;
|
|
|
|
|
const int LAT = 3;
|
|
|
|
|
const int ULAT = 4;
|
|
|
|
|
const int LON = 5;
|
|
|
|
|
const int ULON = 6;
|
|
|
|
|
const int DATE = 9;
|
|
|
|
|
double dvalue;
|
|
|
|
|
int total_fields=0, ivalue;
|
|
|
|
|
char **result = NULL;
|
|
|
|
|
char buffer[128]; // 存储格式化时间的缓冲区
|
|
|
|
|
|
|
|
|
|
if(NULL == curserial)
|
|
|
|
|
return -1;
|
|
|
|
|
/*
|
|
|
|
|
1 $--RMC 字符串 消息 ID,RMC 语句头,’--‘为系统标识
|
|
|
|
|
2 UTCtime hhmmss.ss 当前定位的 UTC 时间
|
|
|
|
|
3 status 字符串 位置有效标志。 V=接收机警告,数据无效 A=数据有效
|
|
|
|
|
4 lat ddmm.mmmmm 纬度,前 2 字符表示度,后面的字符表示分
|
|
|
|
|
5 uLat 字符 纬度方向:N-北,S-南
|
|
|
|
|
6 lon dddmm.mmmmm 经度,前 3 字符表示度,后面的字符表示分
|
|
|
|
|
7 uLon 字符 经度方向:E-东,W-西
|
|
|
|
|
8 spd 数值 对地速度,单位为节
|
|
|
|
|
9 cog 数值 对地真航向,单位为度
|
|
|
|
|
10 date ddmmyy 日期(dd 为日,mm 为月,yy 为年)
|
|
|
|
|
11 mv 数值 磁偏角,单位为度。固定为空
|
|
|
|
|
12 mvE 字符 磁偏角方向:E-东,W-西。固定为空
|
|
|
|
|
13 mode 字符 定位模式标志(备注[1])
|
|
|
|
|
14 navStatus 字符 导航状态标示符(V 表示系统不输出导航状态信息) 仅 NMEA 4.1 及以上版本有效
|
|
|
|
|
15 CS 16 进制数值 校验和,$和*之间(不包括$和*)所有字符的异或结果
|
|
|
|
|
16 <CR><LF> 字符 回车与换行符*/
|
|
|
|
|
|
|
|
|
|
result = BD_NMEA0183_SplitString((char *)curserial->m_au8RecvBuf, &total_fields);
|
|
|
|
|
if(NULL == result)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
dvalue = ::atof(result[UTC_TIME]);
|
|
|
|
|
curserial->bd_data.UTC_time.tm_sec = (int)dvalue%100;
|
|
|
|
|
curserial->bd_data.UTC_time.tm_min = (int)dvalue/100%100;
|
|
|
|
|
curserial->bd_data.UTC_time.tm_hour = (int)dvalue/10000;
|
|
|
|
|
curserial->bd_data.ms_time = (dvalue - ((int)dvalue/1))*1000;
|
|
|
|
|
|
|
|
|
|
curserial->bd_data.status = result[STATUS][0];
|
|
|
|
|
dvalue = ::atof(result[LAT]);
|
|
|
|
|
curserial->bd_data.lat = ((int)dvalue/100)+(dvalue - ((int)dvalue/100*100))/60;
|
|
|
|
|
curserial->bd_data.uLat = result[ULAT][0];
|
|
|
|
|
dvalue = ::atof(result[LON]);
|
|
|
|
|
curserial->bd_data.lon = ((int)dvalue/100)+(dvalue - ((int)dvalue/100*100))/60;
|
|
|
|
|
curserial->bd_data.uLon = result[ULON][0];
|
|
|
|
|
|
|
|
|
|
ivalue = ::atoi(result[DATE]);
|
|
|
|
|
ALOGD("%d", ivalue);
|
|
|
|
|
curserial->bd_data.UTC_time.tm_mday = ivalue/10000;
|
|
|
|
|
ALOGD("D:%d", curserial->bd_data.UTC_time.tm_mday);
|
|
|
|
|
curserial->bd_data.UTC_time.tm_mon = ivalue/100%100-1;
|
|
|
|
|
ALOGD("M:%d", curserial->bd_data.UTC_time.tm_mon);
|
|
|
|
|
curserial->bd_data.UTC_time.tm_year = ivalue%100+100;
|
|
|
|
|
ALOGD("Y:%d", curserial->bd_data.UTC_time.tm_year);
|
|
|
|
|
|
|
|
|
|
::memset(buffer, 0, sizeof(buffer));
|
|
|
|
|
// 使用 strftime 格式化时间
|
|
|
|
|
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &curserial->bd_data.UTC_time);
|
|
|
|
|
DebugLog(0, (char*)buffer, 'I');
|
|
|
|
|
|
|
|
|
|
::sprintf(buffer, "ms:%d lat=%f ulat=%c", curserial->bd_data.ms_time, curserial->bd_data.lat, curserial->bd_data.uLat);
|
|
|
|
|
DebugLog(0, (char*)buffer, 'I');
|
|
|
|
|
::sprintf(buffer, "lon=%f ulon=%c, status=%c", curserial->bd_data.lon, curserial->bd_data.uLon, curserial->bd_data.status);
|
|
|
|
|
DebugLog(0, (char*)buffer, 'I');
|
|
|
|
|
|
|
|
|
|
// 释放内存
|
|
|
|
|
for (int i = 0; i < total_fields; ++i) free(result[i]);
|
|
|
|
|
free(result);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char** BD_NMEA0183_SplitString(char *str, int *total_fields)
|
|
|
|
|
{
|
|
|
|
|
int max_fields, field_count = 0;
|
|
|
|
|
char **fields = NULL, **new_fields = NULL, **result = NULL;
|
|
|
|
|
char *copy = NULL, *p = NULL;
|
|
|
|
|
char szbuf[128];
|
|
|
|
|
|
|
|
|
|
if(NULL == str)
|
|
|
|
|
return NULL;
|
|
|
|
|
if(NULL == total_fields)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
// 创建可修改的副本
|
|
|
|
|
copy = strdup(str);
|
|
|
|
|
memset(szbuf, 0, sizeof(szbuf));
|
|
|
|
|
if (!copy)
|
|
|
|
|
{
|
|
|
|
|
sprintf(szbuf, "内存分配失败\n");
|
|
|
|
|
DebugLog(0, szbuf, 'E');
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始字段数组大小
|
|
|
|
|
max_fields = MAX_FIELDS_NUM;
|
|
|
|
|
fields = (char**)malloc(max_fields * sizeof(char *));
|
|
|
|
|
if (!fields) {
|
|
|
|
|
free(copy);
|
|
|
|
|
sprintf(szbuf, "fields 内存分配失败\n");
|
|
|
|
|
DebugLog(0, szbuf, 'E');
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
field_count = 0;
|
|
|
|
|
fields[field_count] = copy; // 第一个字段起始
|
|
|
|
|
|
|
|
|
|
// 遍历字符串分割字段
|
|
|
|
|
for (p = copy; *p; ++p)
|
|
|
|
|
{
|
|
|
|
|
if (*p == ',')
|
|
|
|
|
{
|
|
|
|
|
*p = '\0'; // 结束当前字段
|
|
|
|
|
field_count++;
|
|
|
|
|
|
|
|
|
|
// 动态扩展数组
|
|
|
|
|
if (field_count >= max_fields) {
|
|
|
|
|
max_fields *= 2;
|
|
|
|
|
new_fields = (char**)realloc(fields, max_fields * sizeof(char *));
|
|
|
|
|
if (!new_fields) {
|
|
|
|
|
free(fields);
|
|
|
|
|
free(copy);
|
|
|
|
|
sprintf(szbuf, "new_fields 内存分配失败\n");
|
|
|
|
|
DebugLog(0, szbuf, 'E');
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
fields = new_fields;
|
|
|
|
|
}
|
|
|
|
|
fields[field_count] = p + 1; // 下一字段起始
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*total_fields = field_count + 1; // 总字段数
|
|
|
|
|
|
|
|
|
|
// 复制字段到独立内存
|
|
|
|
|
result = (char **)malloc((*total_fields) * sizeof(char *));
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
free(fields);
|
|
|
|
|
free(copy);
|
|
|
|
|
sprintf(szbuf, "result 内存分配失败\n");
|
|
|
|
|
DebugLog(0, szbuf, 'E');
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < *total_fields; ++i) {
|
|
|
|
|
result[i] = strdup(fields[i]);
|
|
|
|
|
if (!result[i]) {
|
|
|
|
|
// 释放已分配内存
|
|
|
|
|
for (int j = 0; j < i; ++j) free(result[j]);
|
|
|
|
|
free(result);
|
|
|
|
|
free(fields);
|
|
|
|
|
free(copy);
|
|
|
|
|
sprintf(szbuf, "result 字段复制失败\n");
|
|
|
|
|
DebugLog(0, szbuf, 'E');
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 输出结果到日志
|
|
|
|
|
for (int i = 0; i < *total_fields; ++i)
|
|
|
|
|
{
|
|
|
|
|
sprintf(szbuf, "字段 %2d: %s\n", i + 1, result[i]);
|
|
|
|
|
DebugLog(0, szbuf, 'I');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 释放内存
|
|
|
|
|
//for (int i = 0; i < total_fields; ++i) free(result[i]);
|
|
|
|
|
//free(result);
|
|
|
|
|
free(fields);
|
|
|
|
|
free(copy);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 串口启动接口函数 结束*/
|
|
|
|
|
|
|
|
|
|
/* 数据和图片采集数据返回函数 开始*/
|
|
|
|
|