seg-database-c/src/trans.c
2026-07-10 17:53:18 +08:00

457 lines
11 KiB
C

#ifndef _TYPEDEF_H_
#include "typedef.h"
#endif
#ifndef _SUNYARD_D_H_
#include "sunyard_d.h"
#endif
#ifndef _NETAPI_H_
#include "netapi.h"
#endif
#ifndef _TRANS_H_
#include "trans.h"
#endif
#ifndef _LOG_H_
#include "log.h"
#endif
int Get_retcode(TRD_PKG_ST *pkg)
{
unsigned char cmd[3] = {0};
memcpy(cmd, Get_cmd(pkg), 2);
if ((memcmp(cmd, "\x80\x00" ,2) > 0 && memcmp(cmd, "\x80\x21", 2) < 0) ||
(memcmp(cmd, "\x3E\x80", 2) >= 0 && memcmp(cmd, "\x3E\x90", 2) < 0))
{
return (pkg->data[0]*256 + pkg->data[1]);
}
else
{
return (pkg->data[0] - 0x30)*16 + (pkg->data[1] - 0x30);
}
}
unsigned int Get_sn(TRD_PKG_ST *pkg)
{
return pkg->HEADER[6]*256 + pkg->HEADER[7];
}
char *Get_cmd(TRD_PKG_ST *pkg)
{
return (char *)pkg->COMMAND;
}
int Get_length(TRD_PKG_ST *pkg)
{
return pkg->LENGTH[0]*256 + pkg->LENGTH[1];
}
void Set_sn(TRD_PKG_ST *pkg, unsigned int sn)
{
pkg->HEADER[6] = sn/256;
pkg->HEADER[7] = sn%256;
}
void Set_cmd(TRD_PKG_ST *pkg, char *cmd)
{
if (strlen(cmd) < 2)
{
return;
}
pkg->COMMAND[0] = cmd[0];
pkg->COMMAND[1] = cmd[1];
}
void Set_length(TRD_PKG_ST *pkg, int length)
{
length += 8+2;
pkg->LENGTH[0] = length/256;
pkg->LENGTH[1] = length%256;
}
int Packet_Recv(int fd, TRD_PKG_ST *pkg, int pkgsize)
{
int len = 0,ret = 0;
char *p = NULL;
p = (char *)pkg;
ret = socket_recv(fd, p, 2);
if (ret < 0)
{
return ret;
}
len = Get_length(pkg);
if (len + 2 > pkgsize)
{
return SYD_NET_PKGLEN_ERR;
}
ret=socket_recv(fd, p+2, len);
if (ret < 0)
{
return ret;
}
len += 2;
return len;
}
int Packet_Send(int fd, TRD_PKG_ST *pkg, int pkgsize)
{
int len = 0, ret = 0;
char *p = NULL;
p = (char *)pkg;
len = Get_length(pkg);
len += 2;
if (len + 2 > pkgsize)
{
return SYD_NET_PKGLEN_ERR;
}
ret = socket_send(fd,p,len);
if (ret < 0)
{
return ret;
}
return len;
}
void SetDataLength(int iInData, unsigned char* pcOutData)
{
pcOutData[0] = iInData / 256;
pcOutData[1] = iInData % 256;
}
int GetDataLength(unsigned char* pcInData)
{
return pcInData[0] * 256 + pcInData[1];
}
int Packet_Recv_Noblock(int fd, TRD_PKG_ST *pkg, int pkgsize, struct timeval start_time, int deal_time)
{
int len = 0, ret = 0;
char *p = NULL;
p = (char *)pkg;
ret = socket_recv_noblock(fd, p, 2, start_time, deal_time);
if (ret < 0)
{
return ret;
}
len = Get_length(pkg);
if (len + 2 > pkgsize)
{
return SYD_NET_PKGLEN_ERR;
}
ret = socket_recv_noblock(fd, p + 2, len, start_time, deal_time);
if (ret < 0)
{
return ret;
}
len += 2;
return len;
}
int Packet_Send_Noblock(int fd, TRD_PKG_ST *pkg, int pkgsize, struct timeval start_time, int deal_time)
{
int len = 0, ret = 0;
char *p = NULL;
p = (char *)pkg;
len = Get_length(pkg);
len += 2;
if (len + 2 > pkgsize)
{
return SYD_NET_PKGLEN_ERR;
}
ret = socket_send_noblock(fd, p, len, start_time, deal_time);
if (ret < 0)
{
return ret;
}
return len;
}
int TP_Process_NoBlock_Ordinary(
char *cmd,
TRD_PKG_ST *send_pkg,
TRD_PKG_ST *recv_pkg,
STC_CONNECT_INFO *connect_info,
int *connect_idex,
int device_count,
int deal_time)
{
if(device_count <= 0)
{
LOG("device_count=%d, ret=%08x", device_count, SYD_DEVICE_NUM_ERR);
return SYD_DEVICE_NUM_ERR;
}
struct timeval start_time;
struct timeval local_time;
struct timeval start_switch_time;
struct timeval local_switch_time;
int tmp_dealtime = deal_time / device_count;
int ret = 0, length = 0;
static unsigned short global_sn = 0;
unsigned short local_sn;
local_sn = global_sn;
if(global_sn == 65535)
{
global_sn = 0;
}
else
{
global_sn++;
}
Set_sn(send_pkg,local_sn);
Set_cmd(send_pkg,cmd);
gettimeofday(&start_switch_time, NULL);
/*切换时间开始计时*/
while(1)
{
if(ret < 0)
{
gettimeofday(&local_switch_time, NULL);
if(deal_time < ms_difftime(start_switch_time, local_switch_time))
{
LOG_NET("device switch overtime ret=%08x", SYD_NET_OVERTIME);
return SYD_NET_OVERTIME;
}
}
/*交易起始时间*/
LOG_PrintHex("Send", (unsigned char *)send_pkg, Get_length(send_pkg) + 2);
gettimeofday(&start_time, NULL);
ret = Packet_Send_Noblock(connect_info[*connect_idex].socket_fd, send_pkg, sizeof(TRD_PKG_ST), start_time, tmp_dealtime);
if (ret < 0)
{
if(connect_info[*connect_idex].socket_fd != -1)
{
socket_close_noblock(connect_info[*connect_idex].socket_fd);
connect_info[*connect_idex].socket_fd = -1;
}
/*设置当前连接状态为错误状态*/
connect_info[*connect_idex].status = FALSE;
if(*connect_idex + 1 >= device_count)
{
*connect_idex = 0;
}
else
{
*connect_idex += 1;
}
continue;
}
gettimeofday(&local_time, NULL);
ret = Packet_Recv_Noblock(connect_info[*connect_idex].socket_fd, recv_pkg, sizeof(TRD_PKG_ST), start_time, tmp_dealtime - ms_difftime(start_time, local_time));
if (ret < 0)
{
if(connect_info[*connect_idex].socket_fd != -1)
{
socket_close_noblock(connect_info[*connect_idex].socket_fd);
connect_info[*connect_idex].socket_fd = -1;
}
/*设置当前连接状态为错误状态*/
connect_info[*connect_idex].status = FALSE;
if(*connect_idex + 1 >= device_count)
{
*connect_idex = 0;
}
else
{
*connect_idex += 1;
}
continue;
}
LOG_PrintHex("Recv", (unsigned char *)recv_pkg, Get_length(recv_pkg) + 2);
break;
}
if (Get_sn(recv_pkg) != local_sn)
{
LOG("Get_sn err ret=%08x", SYD_NET_SN_ERR);
return SYD_NET_SN_ERR;
}
cmd[1]++;
if (memcmp(Get_cmd(recv_pkg), cmd, 2))
{
LOG("Get_cmd err ret=%08x", SYD_NET_CMD_ERR);
return SYD_NET_CMD_ERR;
}
ret = Get_retcode(recv_pkg);
if(ret == 0x49)
return SYD_MAC_CHECK_ERROR;
else
return ret;
return 0;
}
int TP_Process_NoBlock_Standby(char *cmd, TRD_PKG_ST *send_pkg, TRD_PKG_ST *recv_pkg, void *device, int deal_time)
{
threadpool_task_t *task_t = (threadpool_task_t *)device;
if(task_t->connect_count <= 0)
{
LOG("task_t->connect_count=%d, ret=%08x", task_t->connect_count, SYD_DEVICE_NUM_ERR);
return SYD_DEVICE_NUM_ERR;
}
struct timeval start_time;
struct timeval local_time;
struct timeval start_switch_time;
struct timeval local_switch_time;
int ret = 0, length = 0;
int tmp_dealtime = deal_time / task_t->connect_count;
static unsigned short global_sn = 0;
unsigned short local_sn;
local_sn = global_sn;
if(global_sn == 65535)
{
global_sn = 0;
}
else
{
global_sn++;
}
Set_sn(send_pkg,local_sn);
Set_cmd(send_pkg,cmd);
/*切换时间开始计时*/
gettimeofday(&start_switch_time, NULL);
while(1)
{
if(ret < 0)
{
gettimeofday(&local_switch_time, NULL);
if(deal_time < ms_difftime(start_switch_time, local_switch_time))
{
LOG_NET("device switch overtime ret=%08x", SYD_NET_OVERTIME);
return SYD_NET_OVERTIME;
}
}
/*交易起始时间*/
gettimeofday(&start_time, NULL);
LOG_PrintHex("Send", (unsigned char *)send_pkg, Get_length(send_pkg) + 2);
ret = Packet_Send_Noblock(task_t->connect_info[task_t->connect_idex].socket_fd, send_pkg, sizeof(TRD_PKG_ST), start_time, tmp_dealtime);
if (ret < 0)
{
if(task_t->connect_info[task_t->connect_idex].socket_fd != -1)
{
socket_close_noblock(task_t->connect_info[task_t->connect_idex].socket_fd);
task_t->connect_info[task_t->connect_idex].socket_fd = -1;
}
/*设置当前连接状态为错误状态*/
task_t->connect_info[task_t->connect_idex].status = FALSE;
if(task_t->connect_idex + 1 >= task_t->connect_count)
{
task_t->connect_idex = 0;
}
else
{
task_t->connect_idex += 1;
}
continue;
}
gettimeofday(&local_time, NULL);
ret = Packet_Recv_Noblock(task_t->connect_info[task_t->connect_idex].socket_fd, recv_pkg, sizeof(TRD_PKG_ST), start_time, tmp_dealtime - ms_difftime(start_time, local_time));
if (ret < 0)
{
if(task_t->connect_info[task_t->connect_idex].socket_fd != -1)
{
socket_close_noblock(task_t->connect_info[task_t->connect_idex].socket_fd);
task_t->connect_info[task_t->connect_idex].socket_fd = -1;
}
/*设置当前连接状态为错误状态*/
task_t->connect_info[task_t->connect_idex].status = FALSE;
if(task_t->connect_idex + 1 >= task_t->connect_count)
{
task_t->connect_idex = 0;
}
else
{
task_t->connect_idex += 1;
}
continue;
}
LOG_PrintHex("Recv", (unsigned char *)recv_pkg, Get_length(recv_pkg) + 2);
break;
}
if (Get_sn(recv_pkg) != local_sn)
{
LOG("Get_sn err ret=%08x", SYD_NET_SN_ERR);
return SYD_NET_SN_ERR;
}
cmd[1]++;
if (memcmp(Get_cmd(recv_pkg), cmd, 2))
{
LOG("Get_cmd err ret=%08x", SYD_NET_CMD_ERR);
return SYD_NET_CMD_ERR;
}
ret = Get_retcode(recv_pkg);
if(ret == 0x49)
return SYD_MAC_CHECK_ERROR;
else
return ret;
return 0;
}
static int *T_Threadpool_PkgDeal(void* arg, void *device)
{
TRD_PKG_THREADPOOL_ST *pkg_threadpool_st = (TRD_PKG_THREADPOOL_ST *)arg;
pkg_threadpool_st->task_ret = TP_Process_NoBlock_Standby(
pkg_threadpool_st->cmd,
&pkg_threadpool_st->send_pkg_st,
&pkg_threadpool_st->recv_pkg_st,
device,
pkg_threadpool_st->deal_time);
pkg_threadpool_st->task_flag = P_THREADAPOOL_PKG_FLAG_OK;
return SYD_OK;
}
int TP_Process_NoBlock(
threadpool_t *threadpool,
pthread_mutex_t *threadpool_mutex,
TRD_PKG_THREADPOOL_ST *pkg_threadpool_st,
int pkg_number)
{
int ret = 0;
struct timeval local_time;
pkg_threadpool_st->task_ret = 0;
pkg_threadpool_st->task_flag = P_THREADAPOOL_PKG_FLAG_FAIL;
pthread_mutex_lock(threadpool_mutex);
ret = threadpool_add_task(threadpool, T_Threadpool_PkgDeal, (void *)pkg_threadpool_st, NULL);
pthread_mutex_unlock(threadpool_mutex);
if(ret != SYD_OK)
{
LOG("threadpool_add_task err ret=%08x", ret);
return ret;
}
if(pkg_number == P_BATCH_ONLY_ONE)
{
while(1)
{
if(pkg_threadpool_st->task_flag == P_THREADAPOOL_PKG_FLAG_OK)
{
return pkg_threadpool_st->task_ret;
}
}
}
return SYD_OK;
}