457 lines
11 KiB
C
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;
|
|
}
|
|
|