|
|
#include "vision.h"
|
|
|
#include "manage.h"
|
|
|
#include "log.h"
|
|
|
#include "ops.h"
|
|
|
|
|
|
//结束符
|
|
|
static const char* _endstr = ";";
|
|
|
static const int _endlen = (int)strlen(_endstr);
|
|
|
|
|
|
CVision::CVision()
|
|
|
{
|
|
|
_len = 0;
|
|
|
_ires = 0;
|
|
|
_port = VPORT;
|
|
|
_skt = INVALID_SKT;
|
|
|
_size = MAX_BUF_LEN;
|
|
|
_msg = new char[_size];
|
|
|
memset(_msg, 0, _size);
|
|
|
_status = SOCKET_DISCONNECTED;
|
|
|
_hReply = sys_CreateEvent(TRUE, FALSE, NULL);
|
|
|
_hSection = sys_InitializeCriticalSection();
|
|
|
}
|
|
|
|
|
|
CVision::~CVision(void)
|
|
|
{
|
|
|
Deinit();
|
|
|
delete _msg;
|
|
|
sys_CloseHandle(_hReply);
|
|
|
sys_DeleteCriticalSection(_hSection);
|
|
|
}
|
|
|
|
|
|
int CVision::Init(const char* pszip, ushort port)
|
|
|
{//任务开始
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
if (INVALID_SKT == _skt)
|
|
|
{
|
|
|
_port = port;
|
|
|
Disconnect();
|
|
|
REPORT("%d 等待连接", _port);
|
|
|
_skt = skt_client(pszip, port);
|
|
|
}
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int CVision::Deinit()
|
|
|
{//关闭任务
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
if (INVALID_SKT != _skt)
|
|
|
{
|
|
|
Disconnect();
|
|
|
skt_close(_skt);
|
|
|
_skt = INVALID_SKT;
|
|
|
REPORT("%d 关闭连接", _port);
|
|
|
}
|
|
|
ClearMsg();
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
void CVision::Connect()
|
|
|
{//等待连接
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
if (INVALID_SKT != _skt &&
|
|
|
SOCKET_CONNECTED != _status &&
|
|
|
SOCKET_CONNECTED == skt_status(_skt))
|
|
|
{
|
|
|
_status = SOCKET_CONNECTED;
|
|
|
_socket = skt_get_socket(_skt);
|
|
|
REPORT("%d 已连接", _port);
|
|
|
}
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
}
|
|
|
|
|
|
void CVision::Disconnect()
|
|
|
{//断开处理
|
|
|
ZERO_CHK(SOCKET_CONNECTED == _status);
|
|
|
|
|
|
_len = 0;
|
|
|
_index = 0;
|
|
|
_socket = 0;
|
|
|
sys_SetEvent(_hReply);
|
|
|
_ires = ERR_NO_CONNECT;
|
|
|
_status = SOCKET_DISCONNECTED;
|
|
|
}
|
|
|
|
|
|
int CVision::Process()
|
|
|
{//拍照处理,等待拍照结果返回 0标识成功 内部阻塞
|
|
|
TOpsCfg cfg;
|
|
|
|
|
|
ops_get_cfg(&cfg);
|
|
|
|
|
|
RETURN_CHK_NOPRT(!cfg.offVision, 0);
|
|
|
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
_ires = ERR_NO_CONNECT;
|
|
|
if (IsConn())
|
|
|
{
|
|
|
_index = 0;
|
|
|
ClearMsg();
|
|
|
sys_ResetEvent(_hReply);
|
|
|
SendMsg("M");
|
|
|
}
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
sys_WaitForSingleObject(_hReply, 5000);
|
|
|
return _ires;
|
|
|
}
|
|
|
|
|
|
int CVision::WaitResult(char* s, int timeout)
|
|
|
{//接收处理结果 一旦接收成功,_res将清空
|
|
|
TOpsCfg cfg;
|
|
|
char* pmsg = NULL;
|
|
|
int ret = ERR_NO_CONNECT;
|
|
|
uint ct = sys_GetTickCount();
|
|
|
|
|
|
RETURN_CHK_NOPRT(s, ERR_INPUT_PARAM);
|
|
|
|
|
|
ops_get_cfg(&cfg);
|
|
|
if (cfg.offVision)
|
|
|
{//禁用
|
|
|
sprintf(s, "0");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
while (ret && IsConn())
|
|
|
{
|
|
|
if (sys_GetTickCount() > ct + timeout)
|
|
|
{//超时
|
|
|
return ERR_TIMEOUT;
|
|
|
}
|
|
|
sys_WaitForSingleObject(_hReply, 50);
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
if (IsConn() && !_lstmsg.empty())
|
|
|
{
|
|
|
ret = 0;
|
|
|
pmsg = _lstmsg.front();
|
|
|
_lstmsg.pop_front();
|
|
|
strcpy(s, pmsg);
|
|
|
delete pmsg;
|
|
|
}
|
|
|
if (_lstmsg.empty()) sys_ResetEvent(_hReply);
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
}
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
void CVision::RecvMsg(char* s, int nsize)
|
|
|
{//接收消息 -- 由线程执行
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
RecvMsgB(s, nsize);
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
}
|
|
|
|
|
|
int CVision::Send(const char* s)
|
|
|
{//发送消息
|
|
|
int ret = 0;
|
|
|
|
|
|
RETURN_CHK_NOPRT(s && *s, ERR_INPUT_PARAM);
|
|
|
RETURN_CHK_NOPRT(IsConn(), ERR_NO_CONNECT);
|
|
|
|
|
|
sys_EnterCriticalSection(_hSection);
|
|
|
ret = SendMsg(s);
|
|
|
sys_LeaveCriticalSection(_hSection);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
int CVision::SendMsg(const char *pszFormat, ...)
|
|
|
{
|
|
|
int len = 0;
|
|
|
int ret = 0;
|
|
|
va_list args;
|
|
|
char buff[MAX_BUF_LEN] = {0};
|
|
|
|
|
|
va_start(args, pszFormat);
|
|
|
len = vsnprintf(buff, MAX_BUF_LEN-1, pszFormat, args);
|
|
|
va_end(args);
|
|
|
|
|
|
RETURN_CHK_NOPRT(len > 0, ERR_INPUT_PARAM);
|
|
|
|
|
|
len += sprintf(buff + len, "%s", _endstr); //增加结束符
|
|
|
|
|
|
ret = skt_send(_skt, buff, len);
|
|
|
if (ERR_NO_CONNECT == ret)
|
|
|
{//已经断开
|
|
|
Disconnect();
|
|
|
REPORT("%d 已断开连接", _port);
|
|
|
return ret;
|
|
|
}
|
|
|
if (ins->visionLog()) LOG_INF1("%d send: %s", _port, buff);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int CVision::FindEnd(char* pszmsg)
|
|
|
{
|
|
|
char* ptmp = NULL;
|
|
|
ptmp = strstr(pszmsg, _endstr);
|
|
|
if (!ptmp) return -1;
|
|
|
*ptmp = 0;
|
|
|
return (int)(ptmp - pszmsg);
|
|
|
}
|
|
|
|
|
|
void CVision::ClearMsg()
|
|
|
{
|
|
|
while (!_lstmsg.empty())
|
|
|
{
|
|
|
FREE_ANY(_lstmsg.front());
|
|
|
_lstmsg.pop_front();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CVision::RecvMsgB(char* s, int nsize)
|
|
|
{//接收消息
|
|
|
int len = 0;
|
|
|
char* pdest = NULL;
|
|
|
|
|
|
ZERO_CHK(SOCKET_CONNECTED == _status);
|
|
|
|
|
|
//len = skt_recv(_skt, _msg + _len, _size - 1 - _len, 0);
|
|
|
len = sys_Recv(_socket, _msg + _len, _size - 1 - _len);
|
|
|
if (ERR_NO_CONNECT == len)
|
|
|
{//已经断开
|
|
|
Disconnect();
|
|
|
REPORT("%d 已断开连接", _port);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
ZERO_CHK(len > 0); //error
|
|
|
|
|
|
if (ins->visionLog()) LOG_INF1("%d recv: %s", _port, _msg + _len);
|
|
|
|
|
|
_len += len; //消息长度
|
|
|
if (_size - 1 == _len)
|
|
|
{//缓冲区不够了 +大
|
|
|
_size += MAX_BUF_LEN;
|
|
|
pdest = new char[_size];
|
|
|
memset(pdest, 0, _size);
|
|
|
memcpy(pdest, _msg, _len);
|
|
|
delete _msg;
|
|
|
_msg = pdest;
|
|
|
}
|
|
|
|
|
|
pdest = _msg;
|
|
|
while(_len > 0)
|
|
|
{
|
|
|
len = FindEnd(pdest); //查找结束符
|
|
|
if (len < 0) break; //未找到结束符
|
|
|
|
|
|
//新消息
|
|
|
if (!s) ParseMsg(pdest);
|
|
|
else
|
|
|
{//需要拷贝到外部
|
|
|
if (nsize < len + 2)
|
|
|
{//buffer 不够
|
|
|
REPORT("%d 接收视觉缓冲区不够,消息不完全接收", _port);
|
|
|
}
|
|
|
else
|
|
|
{//copy
|
|
|
nsize -= len + 1;
|
|
|
s = comm_strcpy(s, pdest);
|
|
|
s = comm_strcpy(s, ";");
|
|
|
}
|
|
|
}
|
|
|
len += _endlen; //加上结束符长度
|
|
|
_len -= len;
|
|
|
pdest += len;
|
|
|
}
|
|
|
|
|
|
if (_len > 0 && pdest != _msg)
|
|
|
{//不等,标识前面已经解析过消息,后面剩余消息需要前移
|
|
|
mem_forward(pdest, _len + 1, (uint)(pdest - _msg));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int CVision::ParseMsg(char* pszmsg)
|
|
|
{
|
|
|
int nlen = 0;
|
|
|
char* ptmp = NULL;
|
|
|
|
|
|
RETURN_CHK_NOPRT(pszmsg, ERR_INPUT_PARAM);
|
|
|
|
|
|
if (ins->visionLog()) LOG_INF1("%d parse msg: %s", _port, pszmsg);
|
|
|
|
|
|
ptmp = sys_strtok(NULL, ",", &pszmsg);
|
|
|
|
|
|
RETURN_CHK_NOPRT(ptmp && *ptmp, ERR_INPUT_PARAM);
|
|
|
|
|
|
if (strcmp(ptmp, "M"))
|
|
|
{//不是拍照返回消息
|
|
|
REPORT("%d 接收到异常指令: %s", _port, ptmp);
|
|
|
return ERR_INPUT_PARAM;
|
|
|
}
|
|
|
|
|
|
RETURN_CHK_NOPRT(pszmsg && *pszmsg, 0);
|
|
|
|
|
|
if (0 == _index)
|
|
|
{//首次返回拍照结果
|
|
|
RETURN_CHK_NOPRT(EMSTR_INT == get_str_type(pszmsg), ERR_INPUT_PARAM);
|
|
|
_ires = atoi(pszmsg); //结果
|
|
|
sys_SetEvent(_hReply);
|
|
|
_index++;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//二次返回、多次返回
|
|
|
ptmp = new char[strlen(pszmsg) + 1];
|
|
|
comm_strcpy(ptmp, pszmsg);
|
|
|
_lstmsg.push_back(ptmp);
|
|
|
sys_SetEvent(_hReply);
|
|
|
return 0;
|
|
|
}
|